Diff for /loncom/homework/structuretags.pm between versions 1.563 and 1.580

version 1.563, 2019/08/11 12:27:11 version 1.580, 2023/11/17 17:02:21
Line 62  use Apache::lonxml; Line 62  use Apache::lonxml;
 use Apache::londefdef;  use Apache::londefdef;
 use Apache::lonenc();  use Apache::lonenc();
 use Apache::loncommon();  use Apache::loncommon();
   use Apache::lonnavmaps;
 use Time::HiRes qw( gettimeofday tv_interval );  use Time::HiRes qw( gettimeofday tv_interval );
   use HTML::Entities();
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use LONCAPA;  use LONCAPA;
     
Line 341  var keypresshandled = 0; Line 343  var keypresshandled = 0;
 var postsubmit = '$postsubmit';  var postsubmit = '$postsubmit';
   
 \$(document).ready(function(){  \$(document).ready(function(){
   if (postsubmit != 'off') {        if (postsubmit != 'off') {
     \$(document).keypress(function(event){      \$(document).keypress(function(event){
         var keycode = (event.keyCode ? event.keyCode : event.which);          var keycode = (event.keyCode ? event.keyCode : event.which);
         if ((keycode == '13') && (keypresshandled == 0)) {          if ((keycode == '13') && (keypresshandled == 0)) {
Line 443  sub page_start { Line 445  sub page_start {
     if (&Apache::lonhtmlcommon::htmlareabrowser()) {      if (&Apache::lonhtmlcommon::htmlareabrowser()) {
         my %textarea_args;          my %textarea_args;
         if (($env{'request.state'} ne 'construct') ||          if (($env{'request.state'} ne 'construct') ||
             ($env{'environment.nocodemirror'})) {              (&Apache::loncommon::nocodemirror())) {
             %textarea_args = (              %textarea_args = (
                                 dragmath => 'math',                                  dragmath => 'math',
                               );                                );
Line 552  sub page_start { Line 554  sub page_start {
      && $env{'request.state'} eq 'construct') {       && $env{'request.state'} eq 'construct') {
  if ($target eq 'web' || $target eq 'edit') {   if ($target eq 'web' || $target eq 'edit') {
             unless ($env{'form.inhibitmenu'} eq 'yes') {              unless ($env{'form.inhibitmenu'} eq 'yes') {
                   my $text = 'Authoring Space';
                   my $href = &Apache::loncommon::authorspace($env{'request.uri'});
                   if ($env{'request.course.id'}) {
                       my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                       my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                       if ($href eq "/priv/$cdom/$cnum/") {
                           $text = &mt('Course Authoring Space');
                       }
                   }
                 # Breadcrumbs for Authoring Space                  # Breadcrumbs for Authoring Space
                 &Apache::lonhtmlcommon::clear_breadcrumbs();                  &Apache::lonhtmlcommon::clear_breadcrumbs();
                 &Apache::lonhtmlcommon::add_breadcrumb({                  &Apache::lonhtmlcommon::add_breadcrumb({
                     'text'  => 'Authoring Space',                      'text'  => $text,
                     'href'  => &Apache::loncommon::authorspace($env{'request.uri'}),                      'href'  => $href,
                 });                  });
                 # breadcrumbs (and tools) will be created                   # breadcrumbs (and tools) will be created 
                 # in start_page->bodytag->innerregister                  # in start_page->bodytag->innerregister
Line 624  sub page_start { Line 635  sub page_start {
         my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();          my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
         my ($path,$multiresp) =           my ($path,$multiresp) = 
             &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);              &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);
         if (($is_task) || ($needs_upload)) {          if ($env{'request.user_in_effect'}) {
               $form_tag_start .= ' onsubmit="preventDefault();"';
           } elsif (($is_task) || ($needs_upload)) {
             $form_tag_start .= ' onsubmit="return file_submission_check(this,'."'$path','$multiresp'".');"';              $form_tag_start .= ' onsubmit="return file_submission_check(this,'."'$path','$multiresp'".');"';
         }          }
  $form_tag_start.='>'."\n";   $form_tag_start.='>'."\n";
Line 667  sub get_resource_name { Line 680  sub get_resource_name {
 }  }
   
 sub setup_rndseed {  sub setup_rndseed {
     my ($safeeval,$target,$probpartlist)=@_;      my ($safeeval,$target,$probpartlist,$prevparttype)=@_;
     my ($symb)=&Apache::lonnet::whichuser();      my ($symb)=&Apache::lonnet::whichuser();
     my ($questiontype,$set_safespace,$rndseed);      my ($questiontype,$set_safespace,$rndseed,$numtries,$reqtries);
     if ($target eq 'analyze') {      if ($target eq 'analyze') {
         $questiontype = $env{'form.grade_questiontype'};          $questiontype = $env{'form.grade_questiontype'};
     }      }
     unless (defined($questiontype)) {      unless (defined($questiontype)) {
         $questiontype = $Apache::lonhomework::type;          $questiontype = $Apache::lonhomework::type;
     }      }
       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")      if (($env{'request.state'} eq "construct")
         || ($symb eq '')          || ($symb eq '')
         || ($Apache::lonhomework::type eq 'practice')          || ($Apache::lonhomework::type eq 'practice')
Line 693  sub setup_rndseed { Line 731  sub setup_rndseed {
                 $env{'form.rndseed'}=$rndseed;                  $env{'form.rndseed'}=$rndseed;
             }              }
  }   }
         if (($env{'request.state'} eq "construct") &&           if ((($env{'request.state'} eq "construct") || ($symb eq '')) &&
             ($Apache::lonhomework::type eq 'randomizetry')) {              ($Apache::lonhomework::type eq 'randomizetry')) {
             my $tries = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.tries"};              if ($numtries) {
             if ($tries) {                  if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
                 $rndseed += $tries;                      my $inc = int($numtries/$reqtries);
                       $rndseed += $inc;
                   } else {
                       $rndseed += $numtries;
                   }
             }              }
             $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed;              $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed;
         }          }
Line 735  sub setup_rndseed { Line 777  sub setup_rndseed {
         }          }
         unless (($target eq 'analyze') && (defined($rndseed))) {          unless (($target eq 'analyze') && (defined($rndseed))) {
             $rndseed=&Apache::lonnet::rndseed();              $rndseed=&Apache::lonnet::rndseed();
             my $partfortries = $Apache::inputtags::part;              my $curr_try = $numtries;
             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"};  
             if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {              if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
                 $curr_try ++;                  $curr_try ++;
             }              }
Line 749  sub setup_rndseed { Line 785  sub setup_rndseed {
                 $rndseed = $1;                  $rndseed = $1;
             }              }
             if ($curr_try) {              if ($curr_try) {
                 my $reqtries = &Apache::lonnet::EXT("resource.$partfortries.randomizeontries");  
                 if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {                  if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
                     my $inc = int(($curr_try-1)/$reqtries);                      my $inc = int(($curr_try-1)/$reqtries);
                     $rndseed += $inc;                      $rndseed += $inc;
Line 762  sub setup_rndseed { Line 797  sub setup_rndseed {
         if ($target eq 'grade') {          if ($target eq 'grade') {
             $Apache::lonhomework::rawrndseed = $rndseed;              $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 ($set_safespace) {
         if ($safeeval) {          if ($safeeval) {
             &Apache::lonxml::debug("Setting rndseed to $rndseed");              &Apache::lonxml::debug("Setting rndseed to $rndseed");
             &Apache::run::run('$external::randomseed="'.$rndseed.'";',$safeeval);              &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 '')) {      unless (($env{'request.state'} eq "construct") || ($symb eq '')) {
Line 791  sub problem_edit_action_button { Line 835  sub problem_edit_action_button {
   
 sub problem_edit_buttons {  sub problem_edit_buttons {
    my ($mode)=@_;     my ($mode)=@_;
      my %editors = &Apache::loncommon::permitted_editors();
 # Buttons that save  # Buttons that save
    my $result = '<div style="float:right">';     my $result = '<div style="float:right">';
    if ($mode eq 'editxml') {     if ($mode eq 'editxml') {
        $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');         if ($editors{'xml'}) {
              $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');
          }
        $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');         $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');
    } else {     } else {
        $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');         if ($editors{'edit'}) {
              $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');
          }
        $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');         $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');
    }     }
    $result.="\n</div>\n";     $result.="\n</div>\n";
Line 805  sub problem_edit_buttons { Line 854  sub problem_edit_buttons {
    $result .= '<div>'.     $result .= '<div>'.
               &problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1);                &problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1);
    if ($mode eq 'editxml') {     if ($mode eq 'editxml') {
        $result.=&problem_edit_action_button('subedit','edit','e','Edit',1);         if ($editors{'edit'}) {
              $result.=&problem_edit_action_button('subedit','edit','e','Edit',1);
          }
        $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1);         $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1);
        if ($env{'environment.nocodemirror'}) {         if (&Apache::loncommon::nocodemirror()) {
            $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1);             $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1);
        }         }
    } else {     } else {
        $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1);         if ($editors{'xml'}) {
              $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1);
          }
        $result.=&problem_edit_action_button('subundo','undo','u','Undo',1);         $result.=&problem_edit_action_button('subundo','undo','u','Undo',1);
    }     }
    $result.="\n</div>";     $result.="\n</div>";
Line 883  sub option { Line 936  sub option {
   
 sub problem_web_to_edit_header {  sub problem_web_to_edit_header {
     my ($rndseed)=@_;      my ($rndseed)=@_;
       my %editors = &Apache::loncommon::permitted_editors();
     my $result .= '<div class="LC_edit_problem_header">';      my $result .= '<div class="LC_edit_problem_header">';
   
     if (!$Apache::lonhomework::parsing_a_task) {      if (!$Apache::lonhomework::parsing_a_task) {
Line 1012  $show_all Line 1066  $show_all
    <hr />     <hr />
    <div>';     <div>';
     $result.='<input type="hidden" name="problemmode" value="view" />';      $result.='<input type="hidden" name="problemmode" value="view" />';
     $result .= '<input type="button" name="submitmode" accesskey="e" value="'.&mt('Edit').'" '.      if ($editors{'edit'}) {
                'onclick="javascript:setmode(this.form,'."'edit'".')" />';          $result .= '<input type="button" name="submitmode" accesskey="e" value="'.&mt('Edit').'" '.
     $result .= '<input type="button" name="submitmode" accesskey="x" value="'.&mt('EditXML').'" '.                     'onclick="javascript:setmode(this.form,'."'edit'".')" />';
                'onclick="javascript:setmode(this.form,'."'editxml'".')" />';      }
     if ($env{'browser.type'} ne 'explorer' || $env{'browser.version'} > 9) {      if ($editors{'xml'}) {
           $result .= '<input type="button" name="submitmode" accesskey="x" value="'.&mt('EditXML').'" '.
                      'onclick="javascript:setmode(this.form,'."'editxml'".')" />';
       }
       if (($editors{'daxe'}) &&
           ($env{'browser.type'} ne 'explorer' || $env{'browser.version'} > 9)) {
         my $uri = $env{'request.uri'};          my $uri = $env{'request.uri'};
         my $daxeurl = '/daxepage'.$uri;          my $daxeurl = '/daxepage'.$uri;
         $result .= '<input type="button" value="'.&mt('Edit with Daxe').'" '.          $result .= '<input type="button" value="'.&mt('Edit with Daxe').'" '.
Line 1057  sub initialize_storage { Line 1116  sub initialize_storage {
  }   }
  %Apache::lonhomework::history=   %Apache::lonhomework::history=
     &Apache::lonnet::tmprestore($namespace,'',$domain,$name);      &Apache::lonnet::tmprestore($namespace,'',$domain,$name);
  my ($temp)=keys(%Apache::lonhomework::history) ;   my ($temp)=keys(%Apache::lonhomework::history);
  &Apache::lonxml::debug("Return message of $temp");   &Apache::lonxml::debug("Return message of $temp");
     } else {      } else {
  %Apache::lonhomework::history=   %Apache::lonhomework::history=
Line 1080  sub initialize_storage { Line 1139  sub initialize_storage {
         &check_correctness_changes() is called in two circumstances          &check_correctness_changes() is called in two circumstances
         in which the results hash is to be stored permanently, for          in which the results hash is to be stored permanently, for
         grading triggered by a student's submission, where feedback on          grading triggered by a student's submission, where feedback on
         correctness is to be provided to the student.           correctness is to be provided to the student.
   
         1. Immediately prior to storing the results hash          1. Immediately prior to storing the results hash
   
         To handle the case where a student's submission (and award) were           To handle the case where a student's submission (and award) were
         stored after history was retrieved in &initialize_storage(), e.g.,          stored after history was retrieved in &initialize_storage(), e.g.,
         if a student submitted answers in quick succession (e.g., from           if a student submitted answers in quick succession (e.g., from
         multiple tabs).  &Apache::inputtags::hidealldata() is called for          multiple tabs).  &Apache::inputtags::hidealldata() is called for
         any parts with out-of-order storage (i.e., correct then incorrect,          any parts with out-of-order storage (i.e., correct then incorrect,
         where awarded >= 1 when correct).          where awarded >= 1 when correct).
Line 1096  sub initialize_storage { Line 1155  sub initialize_storage {
         To handle the case where lond on the student's homeserver returns          To handle the case where lond on the student's homeserver returns
         delay:N -- where N is the number of transactions between the last          delay:N -- where N is the number of transactions between the last
         retrieved in &initialize_storage() and the last stored immediately          retrieved in &initialize_storage() and the last stored immediately
         before permanent storage of the current transaction via           before permanent storage of the current transaction via
         lond::store_handler().  &Apache::grades::makehidden() is called            lond::store_handler().  &Apache::grades::makehidden() is called
         for any parts with out-of-order storage (i.e., correct then incorrect,          for any parts with out-of-order storage (i.e., correct then incorrect,
         where awarded >= 1 when correct).          where awarded >= 1 when correct).
   
  Will call &store_aggregates() to increment totals for attempts,    Will call &store_aggregates() to increment totals for attempts,
         students, and corrects, if running user has student role.          students, and corrects, if running user has student role.
   
 =cut  =cut
Line 1115  sub finalize_storage { Line 1174  sub finalize_storage {
  delete(@Apache::lonhomework::results{@remove});   delete(@Apache::lonhomework::results{@remove});
  my ($symb,$courseid,$domain,$name) =    my ($symb,$courseid,$domain,$name) = 
     &Apache::lonnet::whichuser($given_symb);      &Apache::lonnet::whichuser($given_symb);
         my ($passback,$ltiscope,$ltimap,$ltisymb,$ltiref,$total,$possible,$dopassback);          my ($passback,$pbscope,$pbmap,$pbsymb,$pbtype,$crsdef,$ltinum,
               $ltiref,$total,$possible,$dopassback);
  if ($env{'request.state'} eq 'construct'    if ($env{'request.state'} eq 'construct' 
     || $symb eq ''      || $symb eq ''
     || $Apache::lonhomework::type eq 'practice') {      || $Apache::lonhomework::type eq 'practice') {
Line 1129  sub finalize_storage { Line 1189  sub finalize_storage {
             if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&              if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&
                 (!$Apache::lonhomework::scantronmode) && (!defined($env{'form.grade_symb'})) &&                  (!$Apache::lonhomework::scantronmode) && (!defined($env{'form.grade_symb'})) &&
                 (!defined($env{'form.grade_courseid'}))) {                  (!defined($env{'form.grade_courseid'}))) {
                 if ($env{'request.lti.login'}) {                  if (($env{'request.lti.login'}) || ($env{'request.deeplink.login'})) {
                     my ($map)=&Apache::lonnet::decode_symb($symb);                      my ($map)=&Apache::lonnet::decode_symb($symb);
                     $map = &Apache::lonnet::clutter($map);                      $map = &Apache::lonnet::clutter($map);
                     ($passback,$ltiscope,$ltimap,$ltisymb,$ltiref) =                       if ($env{'request.lti.login'}) {
                         &needs_lti_passback($courseid,$symb,$map);                          ($passback,$pbscope,$pbmap,$pbsymb,$ltinum,$ltiref) =
                               &needs_lti_passback($courseid,$symb,$map);
                       } elsif ($env{'request.deeplink.login'}) {
                           ($passback,$pbscope,$pbmap,$pbsymb,$crsdef,$ltinum,$ltiref) =
                               &needs_linkprot_passback($courseid,$symb,$map);
                       }
                 }                  }
                 if ($Apache::lonhomework::history{'version'}) {                  if ($Apache::lonhomework::history{'version'}) {
                     $laststore = $Apache::lonhomework::history{'version'}.'='.                      $laststore = $Apache::lonhomework::history{'version'}.'='.
Line 1230  sub finalize_storage { Line 1295  sub finalize_storage {
                     }                      }
                 }                  }
             }              }
             if (($dopassback) && ($ltiscope eq 'resource') && ($ltisymb eq $symb)) {              if (($dopassback) && ($pbscope eq 'resource') && ($pbsymb eq $symb)) {
                 $total = 0;                  $total = 0;
                 $possible = 0;                  $possible = 0;
                 my $navmap = Apache::lonnavmaps::navmap->new();                  my $navmap = Apache::lonnavmaps::navmap->new();
Line 1271  sub finalize_storage { Line 1336  sub finalize_storage {
             &store_aggregates($symb,$courseid);              &store_aggregates($symb,$courseid);
             if ($dopassback) {              if ($dopassback) {
                 my $scoreformat = 'decimal';                  my $scoreformat = 'decimal';
                 if (ref($ltiref) eq 'HASH') {                  if (($env{'request.lti.login'}) || ($env{'request.deeplink.login'})) {
                     if ($ltiref->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {                      if (ref($ltiref) eq 'HASH') {
                         $scoreformat = $1;                          if ($ltiref->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
                               $scoreformat = $1;
                           }
                     }                      }
                 }                  }
                   my ($pbid,$pburl,$pbtype);
                   if ($env{'request.lti.login'}) {
                       $pbid = $env{'request.lti.passbackid'};
                       $pburl = $env{'request.lti.passbackurl'};
                       $pbtype = 'lti';
                   } elsif ($env{'request.deeplink.login'}) {
                       $pbid = $env{'request.linkprotpbid'};
                       $pburl = $env{'request.linkprotpburl'};
                       $pbtype = 'linkprot';
                   }
                 my $ltigrade = {                  my $ltigrade = {
                                    'ltinum'   => $ltinum,
                                  'lti'      => $ltiref,                                   'lti'      => $ltiref,
                                    'crsdef'   => $crsdef,
                                  'cid'      => $courseid,                                   'cid'      => $courseid,
                                  'uname'    => $env{'user.name'},                                   'uname'    => $env{'user.name'},
                                  'udom'     => $env{'user.domain'},                                   'udom'     => $env{'user.domain'},
                                  'pbid'     => $env{'request.lti.passbackid'},                                   'pbid'     => $pbid,
                                  'pburl'    => $env{'request.lti.passbackurl'},                                   'pburl'    => $pburl,
                                  'scope'    => $ltiscope,                                   'pbtype'   => $pbtype,
                                  'ltimap'   => $ltimap,                                   'scope'    => $pbscope,
                                  'ltisymb'  => $ltisymb,                                   'pbmap'    => $pbmap,
                                    'pbsymb'   => $pbsymb,
                                  'format'   => $scoreformat,                                   'format'   => $scoreformat,
                                };                                 };
                 if ($ltiscope eq 'resource') {                  if ($pbscope eq 'resource') {
                     $ltigrade->{'total'} = $total;                      $ltigrade->{'total'} = $total;
                     $ltigrade->{'possible'} = $possible;                      $ltigrade->{'possible'} = $possible;
                 }                  }
Line 1309  sub needs_lti_passback { Line 1389  sub needs_lti_passback {
             my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider');              my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider');
             if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') {              if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') {
                 if ($lti{$env{'request.lti.login'}}{'passback'}) {                  if ($lti{$env{'request.lti.login'}}{'passback'}) {
                       my $itemnum = $env{'request.lti.login'};
                     my ($ltiscope,$ltiuri,$ltisymb) =                      my ($ltiscope,$ltiuri,$ltisymb) =
                         &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'},                          &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'},
                                                                $cdom,$cnum,1);                                                                 $cdom,$cnum,1);
Line 1327  sub needs_lti_passback { Line 1408  sub needs_lti_passback {
                             $passback = 1;                              $passback = 1;
                         }                          }
                     }                      }
                     return ($passback,$ltiscope,$ltimap,$ltisymb,$lti{$env{'request.lti.login'}});                      return ($passback,$ltiscope,$ltimap,$ltisymb,$itemnum,$lti{$itemnum});
                 }                  }
             }              }
         }          }
Line 1335  sub needs_lti_passback { Line 1416  sub needs_lti_passback {
     return;      return;
 }  }
   
   sub needs_linkprot_passback {
       my ($courseid,$symb,$map) = @_;
       if (($env{'request.linkprotpbid'}) && ($env{'request.linkprotpburl'})) {
           if ($courseid =~ /^($LONCAPA::match_domain)_($LONCAPA::match_courseid)$/) {
               my ($cdom,$cnum) = ($1,$2);
               my ($deeplink_symb,$deeplink_map,$deeplink,$passback);
               $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom);
               if ($deeplink_symb) {
                   if ($deeplink_symb =~ /\.(page|sequence)$/) {
                       $deeplink_map = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]);
                       my $navmap = Apache::lonnavmaps::navmap->new();
                       if (ref($navmap)) {
                           $deeplink = $navmap->get_mapparam(undef,$deeplink_map,'0.deeplink');
                       }
                   } else {
                       $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$deeplink_symb);
                       $deeplink_map = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[0]);
                   }
                   if (($deeplink ne '') && ($env{'request.linkprot'} ne '')) {
                       my ($itemid,$tinyurl) = split(/:/,$env{'request.linkprot'});
                       if ($itemid =~ /^(\d+)(c|d)$/) {
                           my ($itemnum,$itemtype) = ($1,$2);
                           my ($crsdef,$lti_in_use);
                           if ($itemtype eq 'c') {
                               $crsdef = 1;
                               my %crslti = &Apache::lonnet::get_course_lti($cnum,$cdom,'provider');
                               $lti_in_use = $crslti{$itemnum};
                           } else {
                               my %domlti = &Apache::lonnet::get_domain_lti($cdom,'linkprot');
                               $lti_in_use = $domlti{$itemnum};
                           }
                           my ($state,$others,$listed,$scope,$protect,$display,$target,$exit) = split(/,/,$deeplink);
                           my $passback;
                           if ($scope eq 'resource') {
                               if ($deeplink_symb eq $symb) {
                                   $passback = 1;
                               }
                           } elsif ($scope eq 'map') {
                               if (&Apache::lonnet::clutter($deeplink_map) eq $map) {
                                   $passback = 1;
                               }
                           } elsif ($scope eq 'recurse') {
   #FIXME check if $deeplink_map contains $map
                               $passback = 1;
                           }
                           return ($passback,$scope,$deeplink_map,$deeplink_symb,$crsdef,$itemnum,$lti_in_use);
                       }
                   }
               }
           }
       }
   }
   
 =pod  =pod
   
 =item check_correctness_changes()  =item check_correctness_changes()
   
         For all parts for which current results contain a solved status          For all parts for which current results contain a solved status
         of "incorrect_attempted", check if there was a transaction in which            of "incorrect_attempted", check if there was a transaction in which
         solved was set to "correct_by_student" in the time since the last           solved was set to "correct_by_student" in the time since the last
         transaction (retrieved when &initialize_storage() was called i.e.,           transaction (retrieved when &initialize_storage() was called i.e.,
         when &start_problem() was called), unless:          when &start_problem() was called), unless:
         (a) questiontype parameter is set to survey or anonymous survey (+/- credit)          (a) questiontype parameter is set to survey or anonymous survey (+/- credit)
         (b) problemstatus is set to no or no_feedback_ever          (b) problemstatus is set to no or no_feedback_ever
         If such a transaction exists, and did not occur after "reset status"           If such a transaction exists, and did not occur after "reset status"
         by a user with grading privileges, then the current transaction is an          by a user with grading privileges, then the current transaction is an
         example of an out-of-order transaction (i.e., incorrect occurring after          example of an out-of-order transaction (i.e., incorrect occurring after
         correct).  Accordingly, the current transaction should be hidden.          correct).  Accordingly, the current transaction should be hidden.
Line 1615  sub firstaccess_msg { Line 1749  sub firstaccess_msg {
     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});      my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
     my $buttontext = &mt('Show Resource');      my $buttontext = &mt('Show Resource');
     my $timertext = &mt('Start Timer?');      my $timertext = &mt('Start Timer?');
       my $shownsymb = &HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb),'\'"<>&');
     $result .= (<<ENDCHECKOUT);      $result .= (<<ENDCHECKOUT);
 <form name="markaccess" method="post" action="$uri">  <form name="markaccess" method="post" action="$uri">
 <input type="hidden" name="markaccess" value="yes" />  <input type="hidden" name="markaccess" value="yes" />
   <input type="hidden" name="symb" value="$shownsymb" />
 <input type="button" name="accessbutton" value="$buttontext" onclick="javascript:if (confirm('$timertext')) { document.markaccess.submit(); }" />  <input type="button" name="accessbutton" value="$buttontext" onclick="javascript:if (confirm('$timertext')) { document.markaccess.submit(); }" />
 </form>  </form>
 ENDCHECKOUT  ENDCHECKOUT
Line 1659  sub init_problem_globals { Line 1795  sub init_problem_globals {
     @Apache::structuretags::whilebody=();      @Apache::structuretags::whilebody=();
     @Apache::structuretags::whileline=();      @Apache::structuretags::whileline=();
     $Apache::lonhomework::scantronmode=0;      $Apache::lonhomework::scantronmode=0;
       $Apache::lonhomework::randomizetrypart=0;
     undef($Apache::lonhomework::name);      undef($Apache::lonhomework::name);
     undef($Apache::lonhomework::default_type);      undef($Apache::lonhomework::default_type);
     undef($Apache::lonhomework::type);      undef($Apache::lonhomework::type);
Line 1682  sub reset_problem_globals { Line 1819  sub reset_problem_globals {
     undef($Apache::lonhomework::default_type);      undef($Apache::lonhomework::default_type);
     undef($Apache::lonhomework::type);      undef($Apache::lonhomework::type);
     undef($Apache::lonhomework::scantronmode);      undef($Apache::lonhomework::scantronmode);
       undef($Apache::inputtags::randomizetrypart);
     undef($Apache::lonhomework::ignore_response_errors);      undef($Apache::lonhomework::ignore_response_errors);
     undef(@Apache::functionplotresponse::callscripts);      undef(@Apache::functionplotresponse::callscripts);
     &Apache::lonhomework::reset_show_problem_status();      &Apache::lonhomework::reset_show_problem_status();
Line 1798  sub start_problem { Line 1936  sub start_problem {
     } elsif ((($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) ||      } elsif ((($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) ||
              ($target eq 'answer')) {               ($target eq 'answer')) {
         my ($symb)= &Apache::lonnet::whichuser();          my ($symb)= &Apache::lonnet::whichuser();
         my $navmap = Apache::lonnavmaps::navmap->new();          if ($symb ne '') {
         if (ref($navmap)) {              my $navmap = Apache::lonnavmaps::navmap->new();
             my $res = $navmap->getBySymb($symb);              if (ref($navmap)) {
             if (ref($res)) {                  my $res = $navmap->getBySymb($symb);
                 $probpartlist = $res->parts();                  if (ref($res)) {
                       $probpartlist = $res->parts();
                   }
             }              }
         }          }
     }      }
   
       if (($target eq 'web') && ($env{'request.user_in_effect'})) {
           &Apache::lonxml::get_all_text("/problem",$parser,$style);
           return $result;
       }
   
     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||      if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
         $target eq 'tex') {          $target eq 'tex') {
   
Line 1822  sub start_problem { Line 1967  sub start_problem {
     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||      if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
  $target eq 'tex') {   $target eq 'tex') {
   
           my ($symb) = &Apache::lonnet::whichuser();
  #handle rand seed in construction space   #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);   my $rndseed=&setup_rndseed($safeeval,$target,$probpartlist);
         if (($target eq 'grade') && &Apache::response::submitted()) {          if (($target eq 'grade') && &Apache::response::submitted()) {
             if ($Apache::lonhomework::type eq 'randomizetry') {              if ($Apache::lonhomework::type eq 'randomizetry') {
Line 1837  sub start_problem { Line 1989  sub start_problem {
                 }                  }
             }              }
         }          }
  my ($symb)=&Apache::lonnet::whichuser();  
   
  if ($env{'request.state'} ne "construct" &&    if ($env{'request.state'} ne "construct" && 
     ($symb eq '' || $Apache::lonhomework::type eq 'practice')) {      ($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.='<input type="hidden" name="rndseed" value="'.      $form_tag_start.='<input type="hidden" name="rndseed" value="'.
  $rndseed.'" />'.   $rndseedval.'" />'.
     '<button type="submit" name="resetdata"      '<button type="submit" name="resetdata"
                         value="new_problem_variation">'.&mt('New Problem Variation').'</button>';                          value="new_problem_variation">'.&mt('New Problem Variation').'</button>';
     if (exists($env{'form.username'})) {      if (exists($env{'form.username'})) {
Line 1864  sub start_problem { Line 2019  sub start_problem {
                 $form_tag_start.=&practice_problem_header();                  $form_tag_start.=&practice_problem_header();
             }              }
     $form_tag_start.='<hr />';      $form_tag_start.='<hr />';
         } elsif (($env{'request.state'} ne "construct") &&          }
                  ($Apache::lonhomework::type eq 'randomizetry') &&          if (($env{'request.state'} ne "construct") &&
                  ($status eq 'CAN_ANSWER') &&              ($Apache::lonhomework::type eq 'randomizetry') &&
                  ($env{'course.'.$env{'request.course.id'}.'.type'} ne 'Placement') &&              ($status eq 'CAN_ANSWER') &&
                  (!$env{'request.role.adv'})) {              ($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.   # "New Problem Variation Each Try" header suppressed for Placement Tests, unless course personnel. 
             my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");              my @parts;
             my $problemstatus = &get_problem_status($Apache::inputtags::part);              if (ref($probpartlist) eq 'ARRAY') {
             $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries);                  @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.'";';   my $expression='$external::datestatus="'.$status.'";';
Line 1930  sub start_problem { Line 2092  sub start_problem {
                     $result.= '<button type="submit" name="resetdata" '.                      $result.= '<button type="submit" name="resetdata" '.
                         'value="new_problem_variation">'.&mt('New Problem Variation').'</button>'.                          'value="new_problem_variation">'.&mt('New Problem Variation').'</button>'.
                         &practice_problem_header().'<hr />';                          &practice_problem_header().'<hr />';
                   } 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      # if we are viewing someone else preserve that info
Line 2070  sub end_problem { Line 2236  sub end_problem {
     }      }
  }   }
  $result =~ s/INSERTTEXFRONTMATTERHERE/$frontmatter/;   $result =~ s/INSERTTEXFRONTMATTERHERE/$frontmatter/;
       } elsif ($target eq 'web') {
           if ($env{'request.user_in_effect'}) {
               &reset_problem_globals('problem');
               $result .= &Apache::lonhtmlcommon::set_compute_end_time();
               return $result;
           }
     }      }
   
     my $status=$Apache::inputtags::status['-1'];      my $status=$Apache::inputtags::status['-1'];
Line 2161  sub end_problem { Line 2333  sub end_problem {
     }      }
  }   }
         if ($target eq 'web') {          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";
   <script type="text/javascript">
   // <![CDATA[
       \$(document).ready(function() {
            \$('#LC_randomizetry_header').css('display','block');
       });
   // ]]>
   </script>
   ENDJS
                       }
                   }
               }
         }          }
  if ($target eq 'grade') {   if ($target eq 'grade') {
     &Apache::lonhomework::showhash(%Apache::lonhomework::results);      &Apache::lonhomework::showhash(%Apache::lonhomework::results);
Line 2199  sub end_problem { Line 2388  sub end_problem {
     # computation:      # computation:
     #      #
     if ($target eq 'web') {      if ($target eq 'web') {
         $result .= &Apache::lonhtmlcommon::set_compute_end_time();          $result .= &Apache::lonhtmlcommon::dash_to_minus_js().
                      &Apache::lonhtmlcommon::set_compute_end_time();
         #          #
         # Closing tags delayed so any <script></script> tags           # Closing tags delayed so any <script></script> tags 
         # not in head can appear inside body, for valid xhtml.          # not in head can appear inside body, for valid xhtml.
Line 2886  sub start_part { Line 3076  sub start_part {
         if (($target eq 'grade') && &Apache::response::submitted()) {          if (($target eq 'grade') && &Apache::response::submitted()) {
             $Apache::lonhomework::results{"resource.$id.rndseed"}=$rndseed;              $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()) {      } elsif (($target eq 'grade') && &Apache::response::submitted()) {
         $Apache::lonhomework::results{"resource.$id.rndseed"}=$Apache::lonhomework::rawrndseed;          $Apache::lonhomework::results{"resource.$id.rndseed"}=$Apache::lonhomework::rawrndseed;
     }      }
Line 2961  sub start_part { Line 3159  sub start_part {
  } elsif ($target eq 'web') {   } elsif ($target eq 'web') {
                     if ($status eq 'CAN_ANSWER') {                      if ($status eq 'CAN_ANSWER') {
                         my $problemstatus = &get_problem_status($Apache::inputtags::part);                           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;                          my $num = scalar(@Apache::inputtags::partlist)-1;
                         if ($probrandomize eq 'randomizetry') {                          if ((($Apache::lonhomework::default_type eq 'randomizetry') || 
                             if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") ne 'randomizetry') {                              ($Apache::lonhomework::randomizetrypart)) &&
                                 $result .= &randomizetry_part_header($problemstatus,'none',$num);                              ($Apache::lonhomework::type ne 'randomizetry')) {
                             } else {                              $result .= &randomizetry_part_header($problemstatus,'none',$num);
                                 my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");                          } elsif ($Apache::lonhomework::type eq 'randomizetry') {
                                 if ($probrandtries ne $reqtries) {                              $Apache::lonhomework::randomizetrypart = 1;
                                     $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);                              my $reqtries = &Apache::lonnet::EXT("resource.$id.randomizeontries");
                                 }  
                             }  
                         } elsif (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") eq 'randomizetry') {  
                             my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");  
                             $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);                              $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);
                         }                          }
                     }                      }
Line 3029  sub end_part { Line 3221  sub end_part {
     $gradestatus='';      $gradestatus='';
  }   }
  $result.=$gradestatus;   $result.=$gradestatus;
  if ($$tagstack[-2] eq 'td' and $target eq 'tex') {$result.='\end{minipage}';}    if ($$tagstack[-2] eq 'td' and $target eq 'tex') {
               if (not $env{'form.problem_split'}=~/yes/) {
                   $result.='\end{minipage}';
               }
           }
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
  $result.=&Apache::edit::end_table();   $result.=&Apache::edit::end_table();
     } elsif ($target eq 'modified') {      } elsif ($target eq 'modified') {
Line 3194  sub end_startouttext { Line 3390  sub end_startouttext {
                  .&Apache::edit::deletelist($target,$token)                   .&Apache::edit::deletelist($target,$token)
                  .'</span></td>'                   .'</span></td>'
          .'<td><span id="math_'.$areaid.'">';           .'<td><span id="math_'.$areaid.'">';
  if ($env{'environment.nocodemirror'}) {   if (&Apache::loncommon::nocodemirror()) {
     $result.=&Apache::lonhtmlcommon::dragmath_button($areaid,1);      $result.=&Apache::lonhtmlcommon::dragmath_button($areaid,1);
  } else {   } else {
     $result.='&nbsp;';      $result.='&nbsp;';
Line 3294  sub practice_problem_header { Line 3490  sub practice_problem_header {
 }  }
   
 sub randomizetry_problem_header {  sub randomizetry_problem_header {
     my ($problemstatus,$reqtries) = @_;      my ($problemstatus,$reqtries,$symb) = @_;
     my ($header,$text);      my ($header,$text);
     if ($reqtries > 1) {      if ($reqtries > 1) {
         $header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries);          $header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries);
Line 3314  sub randomizetry_problem_header { Line 3510  sub randomizetry_problem_header {
             $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.');              $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.');
         }          }
     }      }
     return '<h3 class="LC_info">'.$header.'</h3>'.      if (($env{'request.state'} eq "construct") || ($symb eq '')) {
            '<span class="LC_info">'.$text.'</span><hr />';          return '<div class="LC_info" id="LC_randomizetry_header" style="display:none">'.
                  '<h3>'.$header.'</h3><span class="LC_info">'.$text.'</span><hr /></div>';
       } else {
           return '<h3 class="LC_info">'.$header.'</h3>'.
                  '<span class="LC_info">'.$text.'</span><hr />';
       }
 }  }
   
 sub randomizetry_part_header {  sub randomizetry_part_header {
Line 3323  sub randomizetry_part_header { Line 3524  sub randomizetry_part_header {
     my ($header,$text);      my ($header,$text);
     if ($reqtries eq 'none') {      if ($reqtries eq 'none') {
         $header = &mt('No Question Variation');          $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) {      } elsif ($reqtries > 1) {
         $header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries);          $header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries);
         if (($problemstatus eq 'no') ||          if (($problemstatus eq 'no') ||

Removed from v.1.563  
changed lines
  Added in v.1.580


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>