Diff for /loncom/homework/structuretags.pm between versions 1.512.2.3 and 1.528

version 1.512.2.3, 2013/06/05 15:37:26 version 1.528, 2015/02/22 01:34:48
Line 225  sub end_tex { Line 225  sub end_tex {
   
 sub homework_js {  sub homework_js {
     return &Apache::loncommon::resize_textarea_js().      return &Apache::loncommon::resize_textarea_js().
                   &Apache::loncommon::colorfuleditor_js().
            &setmode_javascript().             &setmode_javascript().
  <<'JS';   <<'JS';
 <script type="text/javascript">  <script type="text/javascript">
Line 254  function image_response_click (which, e) Line 255  function image_response_click (which, e)
     input_element.value = click;      input_element.value = click;
     img_element.src = '/adm/randomlabel.png?token='+token+'&clickdata='+click;      img_element.src = '/adm/randomlabel.png?token='+token+'&clickdata='+click;
 }  }
   
   var submithandled = 0;
   var keypresshandled = 0;
   
   $(document).ready(function(){
   
       $(document).keypress(function(event){
           var keycode = (event.keyCode ? event.keyCode : event.which);
           if ((keycode == '13') && (keypresshandled == 0)) {
               if ( $( document.activeElement ).hasClass("LC_textline") ) {
                   keypresshandled = 1;
                   var idsArray = $( document.activeElement ).attr("id").split(/HWVAL_/);
                   if (idsArray.length) {
                       event.preventDefault();
                       var itemsArray = idsArray[1].split(/_/);
                       var buttonId = idsArray[0]+'submit_'+itemsArray[0];
                       $("#"+buttonId).trigger("click");
                   }
               }
           }
       });
   
       $(document).delegate('form :submit', 'click', function( event ) {
           if ( $( this ).hasClass( "LC_hwk_submit" ) ) {
               var buttonId = this.id;
               if (submithandled == 0) {
                   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 (buttonId != "all_submit") {
                           $( ".LC_status_"+buttonId ).hide();
                           if (( "#"+buttonId+"_pressed" ).length) {
                               $( "#"+buttonId+"_pressed" ).val( "1" );
                           }
                       }
                   } else {
                       $( ".LC_status_"+buttonId ).hide();
                   }
                   $(this.form).submit();
                   $( ".LC_hwk_submit" ).prop( "disabled", true);
                   $( ".LC_textline" ).prop( "readonly", "readonly");
                   event.preventDefault();
                   return true;
               }
           }
       });
   });
   
 // ]]>  // ]]>
 </script>  </script>
 JS  JS
Line 297  sub page_start { Line 347  sub page_start {
         $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args);          $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args);
     }      }
     my $is_task = ($env{'request.uri'} =~ /\.task$/);      my $is_task = ($env{'request.uri'} =~ /\.task$/);
     my $needs_upload;      my ($needs_upload,$partlist);
     my ($symb)= &Apache::lonnet::whichuser();      my ($symb)= &Apache::lonnet::whichuser();
     my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);      my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
     if ($is_task) {      if ($is_task) {
Line 315  sub page_start { Line 365  sub page_start {
                     unless ($is_page) {                      unless ($is_page) {
                         $needs_upload = 1;                          $needs_upload = 1;
                     }                      }
                       if ((ref($tagstack) eq 'ARRAY') && ($tagstack->[-1] eq 'problem')) {
                           my $res = $navmap->getBySymb($symb);
                           if (ref($res)) {
                               $partlist = $res->parts();
                           }
                       }
                 }                  }
             }              }
         } else {          } else {
Line 326  sub page_start { Line 382  sub page_start {
                     if (ref($mapres)) {                      if (ref($mapres)) {
                         $is_page = $mapres->is_page();                          $is_page = $mapres->is_page();
                     }                      }
                     unless ($is_page) {                      if ($is_page) {
                           if ((ref($tagstack) eq 'ARRAY') && ($tagstack->[-1] eq 'problem')) {
                               my $res = $navmap->getBySymb($symb);
                               if (ref($res)) {
                                   $partlist = $res->parts();
                               }
                           }
                       } else {
                         my $res = $navmap->getBySymb($symb);                          my $res = $navmap->getBySymb($symb);
                         if (ref($res)) {                          if (ref($res)) {
                             my $partlist = $res->parts();                              $partlist = $res->parts();
                             if (ref($partlist) eq 'ARRAY') {                              if (ref($partlist) eq 'ARRAY') {
                                 foreach my $part (@{$partlist}) {                                  foreach my $part (@{$partlist}) {
                                     my @types = $res->responseType($part);                                      my @types = $res->responseType($part);
Line 370  sub page_start { Line 433  sub page_start {
  "if (typeof swmenu != 'undefined') {swmenu.currentURL=null;}\n".   "if (typeof swmenu != 'undefined') {swmenu.currentURL=null;}\n".
  &Apache::loncommon::browser_and_searcher_javascript().   &Apache::loncommon::browser_and_searcher_javascript().
                 "\n</script>\n";                  "\n</script>\n";
               if ($target eq 'edit') {
                   $extra_head .= &Apache::edit::js_update_linknum();
               }
  }   }
     }      }
   
Line 414  sub page_start { Line 480  sub page_start {
         $body_args{'add_entries'}    = \%add_entries;          $body_args{'add_entries'}    = \%add_entries;
         if ( $env{'request.state'} eq   'construct') {          if ( $env{'request.state'} eq   'construct') {
             $body_args{'only_body'}  = 1;              $body_args{'only_body'}  = 1;
           } elsif ($target eq 'web') {
               $body_args{'print_suppress'} = 1;
         }          }
     }      }
     $body_args{'no_auto_mt_title'} = 1;      $body_args{'no_auto_mt_title'} = 1;
Line 460  sub page_start { Line 528  sub page_start {
  "\t".'<input type="hidden" name="symb" value="'.$symb.'" />'."\n";   "\t".'<input type="hidden" name="symb" value="'.$symb.'" />'."\n";
  }   }
     }      }
     return ($page_start,$form_tag_start);      return ($page_start,$form_tag_start,$partlist);
 }  }
   
 #use Time::HiRes();  #use Time::HiRes();
Line 491  sub get_resource_name { Line 559  sub get_resource_name {
 }  }
   
 sub setup_rndseed {  sub setup_rndseed {
     my ($safeeval,$target)=@_;      my ($safeeval,$target,$probpartlist)=@_;
     my ($symb)=&Apache::lonnet::whichuser();      my ($symb)=&Apache::lonnet::whichuser();
     my ($questiontype,$set_safespace,$rndseed);      my ($questiontype,$set_safespace,$rndseed);
     if ($target eq 'analyze') {      if ($target eq 'analyze') {
Line 552  sub setup_rndseed { Line 620  sub setup_rndseed {
         }          }
         unless (($target eq 'analyze') && (defined($rndseed))) {          unless (($target eq 'analyze') && (defined($rndseed))) {
             $rndseed=&Apache::lonnet::rndseed();              $rndseed=&Apache::lonnet::rndseed();
             my $curr_try = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.tries"};              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"};
             if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {              if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
                 $curr_try ++;                  $curr_try ++;
             }              }
Line 560  sub setup_rndseed { Line 634  sub setup_rndseed {
                 $rndseed = $1;                  $rndseed = $1;
             }              }
             if ($curr_try) {              if ($curr_try) {
                 my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");                  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 570  sub setup_rndseed { Line 644  sub setup_rndseed {
             }              }
         }          }
         $set_safespace = 1;          $set_safespace = 1;
           if ($target eq 'grade') {
               $Apache::lonhomework::rawrndseed = $rndseed;
           }
     }      }
     if ($set_safespace) {      if ($set_safespace) {
         if ($safeeval) {          if ($safeeval) {
Line 624  sub problem_edit_buttons { Line 701  sub problem_edit_buttons {
    return $result;     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(<FH>){
                   $code.= $_ unless $_ =~ /(<problem>)|(<\/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 = '
   <translated>
       <lang which="en"></lang>
       <lang which="default"></lang>
   </translated>';
   
    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|\n|\\r\\n|g;
           $return =~ s|'|\\'|g;
    $return =~ s|&#39;|\\&#39;|g;
       return $return;
   }
   
 sub problem_edit_header {  sub problem_edit_header {
     return '<input type="hidden" name="submitted" value="edit" />'.      my ($mode)=@_;
       my $return = '<input type="hidden" name="submitted" value="edit" />'.
  &remember_problem_state('edit').'   &remember_problem_state('edit').'
 <div class="LC_edit_problem_header">          <div class="LC_edit_problem_header">
 <div class="LC_edit_problem_header_title">          <div class="LC_edit_problem_header_title">
 '.&mt('Problem Editing').&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'          '.&mt('Problem Editing').$mode.&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'
 </div>'.          </div><div class="LC_edit_actionbar" id="actionbar">'.
 '<input type="hidden" name="problemmode" value="saveedit" />'.          '<input type="hidden" name="problemmode" value="saveedit" />'.
 &problem_edit_buttons().'          &problem_edit_buttons();
 <hr style="clear:both;" />  
 '.&Apache::lonxml::message_location().'      $return.='<hr style="clear:both;visibility:hidden;" />
 </div>      </div></div>'
 '.      .&Apache::lonxml::message_location();
        '<table border="0" width="100%"><tr><td bgcolor="#F8F8F8">';      $return .= '<link rel="stylesheet" href="/adm/codemirror/codemirror-combined.css" />
       <script type="text/javascript" src="/adm/codemirror/codemirror-compressed-colorful.js"></script>';
   
       $return .= '<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script>
           <script type="text/javascript">
               // unless internet explorer
               if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){
                   $(document).ready(
                       function() {
                           $(\'.LC_edit_actionbar\').scrollToFixed(
                               {
                                   fixed: function(){
                                       $(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
                                   }
                               }
                           );
                       }
                   );
               }
           </script>
           <table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';
       return $return;
 }  }
   
 sub problem_edit_footer {  sub problem_edit_footer {
       my $resource = $env{'request.ambiguous'};
     return '</td></tr></table><br />      return '</td></tr></table><br />
 <div class="LC_edit_problem_footer">  <div class="LC_edit_problem_footer">
   <hr />'.    <hr />'.
 &problem_edit_buttons().'  &problem_edit_buttons().'
   <hr style="clear:both;" />    <hr style="clear:both;" />
     <script type="text/javascript">
         restoreState("'.$resource.'");
         restoreScrollPosition("'.$resource.'");
     </script>
 </div>  </div>
 '.  '.
     "\n</form>\n".&Apache::loncommon::end_page();      "\n</form>\n".&Apache::loncommon::end_page();
Line 710  sub problem_web_to_edit_header { Line 1018  sub problem_web_to_edit_header {
 ".&mt("Problem Type:")."  ".&mt("Problem Type:")."
 <select name='problemtype'>  <select name='problemtype'>
   <option value=''></option>    <option value=''></option>
   ".&option('exam'   ,'problemtype').&mt("Exam Problem")."</option>    ".&option('exam'   ,'problemtype').&mt("Bubblesheet Exam Problem")."</option>
   ".&option('problem','problemtype').&mt("Homework Problem")."</option>    ".&option('problem','problemtype').&mt("Homework Problem")."</option>
   ".&option('survey' ,'problemtype').&mt("Survey Question")."</option>    ".&option('survey' ,'problemtype').&mt("Survey Question")."</option>
   ".&option('surveycred' ,'problemtype').&mt("Survey Question (with credit)")."</option>    ".&option('surveycred' ,'problemtype').&mt("Survey Question (with credit)")."</option>
Line 728  $show_all Line 1036  $show_all
 <select name='problemstatus'>  <select name='problemstatus'>
   <option value=''></option>    <option value=''></option>
   ".&option('yes','problemstatus').&mt("Show Feedback")."</option>    ".&option('yes','problemstatus').&mt("Show Feedback")."</option>
   ".&option('no', 'problemstatus').&mt("Don't Show Incorect/Correct Feedback")."</option>    ".&option('no', 'problemstatus').&mt("Don't Show Incorrect/Correct Feedback")."</option>
   ".&option('no_feedback_ever', 'problemstatus').&mt("Don't Show Any Feedback")."</option>    ".&option('no_feedback_ever', 'problemstatus').&mt("Don't Show Any Feedback")."</option>
 </select>  </select>
 </span>  </span>
Line 830  sub initialize_storage { Line 1138  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 838  sub initialize_storage { Line 1146  sub initialize_storage {
     }      }
   
     #ignore error conditions      #ignore error conditions
     my ($temp)=keys %Apache::lonhomework::history ;      my ($temp)=keys(%Apache::lonhomework::history);
     if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); }      if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); }
 }  }
   
Line 846  sub initialize_storage { Line 1154  sub initialize_storage {
   
 =item finalize_storage()  =item finalize_storage()
   
  Stores away the result has to a student's environment   Stores away the result hash to a student's environment;
  checks form.grade_ for specific values, other wises stores   checks form.grade_ for specific values, otherwise stores
  to the running users environment   to the running user's environment.
  Will increment totals for attempts, students, and corrects  
  if running user has student role.          &check_correctness_changes() is called in two circumstances
           in which the results hash is to be stored permanently, for
           grading triggered by a student's submission, where feedback on
           correctness is to be provided to the student. 
   
           1. Immediately prior to storing the results hash
   
           To handle the case where a student's submission (and award) were 
           stored after history was retrieved in &initialize_storage(), e.g.,
           if a student submitted answers in quick succession (e.g., from 
           multiple tabs).  &Apache::inputtags::hidealldata() is called for
           any parts with out-of-order storage (i.e., correct then incorrect,
           where awarded >= 1 when correct).
   
           2. Immediately after storing the results hash
   
           To handle the case where lond on the student's homeserver returns
           delay:N -- where N is the number of transactions between the last
           retrieved in &initialize_storage() and the last stored immediately
           before permanent storage of the current transaction via 
           lond::store_handler().  &Apache::grades::makehidden() is called  
           for any parts with out-of-order storage (i.e., correct then incorrect,
           where awarded >= 1 when correct).
   
    Will call &store_aggregates() to increment totals for attempts, 
           students, and corrects, if running user has student role.
   
 =cut  =cut
   
   
Line 872  sub finalize_storage { Line 1205  sub finalize_storage {
       $namespace,'',$domain,$name);        $namespace,'',$domain,$name);
     &Apache::lonxml::debug('Construct Store return message:'.$result);      &Apache::lonxml::debug('Construct Store return message:'.$result);
  } else {   } else {
               my ($laststore,$checkedparts,@parts,%postcorrect);
               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 ($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);
                   if ($record{'version'}) {
                       my ($newversion,$oldversion,$oldtimestamp);
                       if ($Apache::lonhomework::history{'version'}) {
                           $oldversion = $Apache::lonhomework::history{'version'};
                           $oldtimestamp = $Apache::lonhomework::history{'timestamp'};
                       } else {
                           $oldversion = 0;
                           $oldtimestamp = 0;
                       }
                       if ($record{'version'} > $oldversion) {
                           if ($record{'timestamp'} >= $oldtimestamp) {
                               $laststore = $record{'version'}.'='.$record{'timestamp'};
                               $newversion = $record{'version'} + 1;
                               $checkedparts = 1;
                               foreach my $key (keys(%Apache::lonhomework::results)) {
                                   if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                                       my $part = $1;
                                       if ($Apache::lonhomework::results{$key} eq 'incorrect_attempted') {
                                           push(@parts,$part);
                                       }
                                   }
                               }
                               if (@parts) {
                                   my @parts_to_hide = &check_correctness_changes($symb,$courseid,$domain,$name,
                                                                                  \%record,\@parts,$newversion,
                                                                                  $oldversion);
                                   if (@parts_to_hide) {
                                       foreach my $part (@parts_to_hide) {
                                           $postcorrect{$part} = 1;
                                           &Apache::inputtags::hidealldata($part);
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
     $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results,      $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results,
     $symb,$courseid,$domain,$name);      $symb,$courseid,$domain,$name,$laststore);
               if ($result =~ /^delay\:(\d+)$/) {
                   my $numtrans = $1;
                   my ($oldversion) = split(/=/,$laststore);
                   if ($numtrans) {
                       my $newversion = $oldversion + 1 + $numtrans;
                       my @possparts;
                       if ($checkedparts) {
                           foreach my $part (@parts) {
                               unless ($postcorrect{$part}) {
                                   push(@possparts,$part);
                               }
                           }
                       } else {
                           foreach my $key (keys(%Apache::lonhomework::results)) {
                               if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                                   my $part = $1;
                                   unless ($postcorrect{$part}) {
                                       if ($Apache::lonhomework::results{$key} eq 'incorrect_attempted') {
                                           push(@possparts,$part);
                                       }
                                   }
                               }
                           }
                       }
                       if (@possparts) {
                           my %newrecord = &Apache::lonnet::restore($symb,$courseid,$domain,$name);
                           my @parts_to_hide = &check_correctness_changes($symb,$courseid,$domain,$name,
                                                                          \%newrecord,\@possparts,$newversion,
                                                                          $oldversion);
                           if (@parts_to_hide) {
                               my $partslist = join(',',@parts_to_hide);
                               &Apache::grades::makehidden($newversion,$partslist,\%newrecord,$symb,$domain,$name,1);
                           }
                       }
                   }
               }
     &Apache::lonxml::debug('Store return message:'.$result);      &Apache::lonxml::debug('Store return message:'.$result);
             &store_aggregates($symb,$courseid);              &store_aggregates($symb,$courseid);
  }   }
Line 885  sub finalize_storage { Line 1302  sub finalize_storage {
   
 =pod  =pod
   
   =item check_correctness_changes()
   
           For all parts for which current results contain a solved status
           of "incorrect_attempted", check if there was a transaction in which  
           solved was set to "correct_by_student" in the time since the last 
           transaction (retrieved when &initialize_storage() was called i.e., 
           when &start_problem() was called), unless:
           (a) questiontype parameter is set to survey or anonymous survey (+/- credit)
           (b) problemstatus is set to no or no_feedback_ever
           If such a transaction exists, and did not occur after "reset status" 
           by a user with grading privileges, then the current transaction is an
           example of an out-of-order transaction (i.e., incorrect occurring after
           correct).  Accordingly, the current transaction should be hidden.
   
   =cut
   
   
   sub check_correctness_changes {
       my ($symb,$courseid,$domain,$name,$record,$parts,$newversion,$oldversion) = @_;
       my @parts_to_hide;
       unless ((ref($record) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
           return @parts_to_hide;
       }
       if (@{$parts}) {
           my $usec;
           if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&
               ($env{'request.course.id'} eq $courseid)) {
               $usec = $env{'request.course.sec'};
           } else {
               $usec = &Apache::lonnet::getsection($domain,$name,$courseid);
           }
           foreach my $id (@{$parts}) {
               next if (($Apache::lonhomework::results{'resource.'.$id.'.type'} =~ /survey/) ||
                        (&Apache::lonnet::EXT("resource.$id.problemstatus",$symb,
                                              $domain,$name,$usec,undef,$courseid) =~ /^no/));
               my $reset;
               for (my $i=$newversion-1; $i>=$oldversion; $i--) {
                   if (($record->{$i.':resource.'.$id.'.regrader'}) &&
                       ($record->{$i.':resource.'.$id.'.tries'} eq '') &&
                       ($record->{$i.':resource.'.$id.'.award'} eq '')) {
                       $reset = 1;
                   } elsif (($record->{$i.":resource.$id.solved"} eq 'correct_by_student') &&
                            ($record->{$i.":resource.$id.awarded"} >= 1)) {
                       unless ($reset) {
                           push(@parts_to_hide,$id);
                           last;
                       }
                   }
               }
           }
       }
       return @parts_to_hide;
   }
   
   =pod
   
 item store_aggregates()  item store_aggregates()
   
  Sends hash of values to be incremented in nohist_resourcetracker.db   Sends hash of values to be incremented in nohist_resourcetracker.db
Line 947  sub store_aggregates { Line 1420  sub store_aggregates {
             }              }
         }          }
     }      }
     if (keys (%aggregate) > 0) {      if (keys(%aggregate) > 0) {
  &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,   &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
                             $cdomain,$cname);                              $cdomain,$cname);
     }      }
Line 966  sub checkout_msg { Line 1439  sub checkout_msg {
  'resource'=>'The resource needs to be checked out',   'resource'=>'The resource needs to be checked out',
  'id_expln'=>'As a resource gets checked out, a unique timestamped ID is given to it, and a permanent record is left in the system.',   'id_expln'=>'As a resource gets checked out, a unique timestamped ID is given to it, and a permanent record is left in the system.',
                 'warning'=>'Checking out resources is subject to course policies, and may exclude future credit even if done erroneously.',                  'warning'=>'Checking out resources is subject to course policies, and may exclude future credit even if done erroneously.',
                 'checkout'=>'Check out Exam for Viewing',                  'checkout'=>'Check out Bubblesheet Exam for Viewing',
  'checkout?'=>'Check out Exam?');   'checkout?'=>'Check out Bubblesheet Exam?');
     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});      my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
     return (<<ENDCHECKOUT);      return (<<ENDCHECKOUT);
 <h2>$lt{'resource'}</h2>  <h2>$lt{'resource'}</h2>
Line 975  sub checkout_msg { Line 1448  sub checkout_msg {
 <p class="LC_warning">$lt{'warning'}</p>  <p class="LC_warning">$lt{'warning'}</p>
 <form name="checkout" method="post" action="$uri">  <form name="checkout" method="post" action="$uri">
 <input type="hidden" name="doescheckout" value="yes" />  <input type="hidden" name="doescheckout" value="yes" />
 <input type="button" name="checkoutbutton" value="$lt{'checkout'}" onClick="javascript:if (confirm('$lt{'checkout?'}')) { document.checkout.submit(); }" />  <input type="button" name="checkoutbutton" value="$lt{'checkout'}" onclick="javascript:if (confirm('$lt{'checkout?'}')) { document.checkout.submit(); }" />
 </form>  </form>
 ENDCHECKOUT  ENDCHECKOUT
 }  }
Line 1009  sub firstaccess_msg { Line 1482  sub firstaccess_msg {
     $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="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
     return $result;      return $result;
Line 1061  sub reset_problem_globals { Line 1534  sub reset_problem_globals {
     undef($Apache::inputtags::part);      undef($Apache::inputtags::part);
     if ($type eq 'Task') {      if ($type eq 'Task') {
         undef($Apache::inputtags::slot_name);          undef($Apache::inputtags::slot_name);
       } elsif ($type eq 'problem') {
           undef($Apache::lonhomework::rawrndseed);
     }      }
 #don't undef this, lonhomework.pm takes care of this, we use this to   #don't undef this, lonhomework.pm takes care of this, we use this to 
 #detect if we try to do 2 problems in one file  #detect if we try to do 2 problems in one file
Line 1162  sub start_problem { Line 1637  sub start_problem {
     my $resource_due;      my $resource_due;
   
     my $name= &get_resource_name($parstack,$safeeval);      my $name= &get_resource_name($parstack,$safeeval);
     my ($result,$form_tag_start,$slot_name,$slot);      my ($result,$form_tag_start,$slot_name,$slot,$probpartlist);
   
     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') {
         if ($env{'form.markaccess'}) {          if ($env{'form.markaccess'}) {
             my @interval=&Apache::lonnet::EXT("resource.0.interval");              my @interval=&Apache::lonnet::EXT("resource.0.interval");
             &Apache::lonnet::set_first_access($interval[1]);              &Apache::lonnet::set_first_access($interval[1],$interval[0]);
         }          }
   
         ($status,$accessmsg,$slot_name,$slot) =          ($status,$accessmsg,$slot_name,$slot) =
Line 1178  sub start_problem { Line 1653  sub start_problem {
   
     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'      if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'
  || $target eq 'edit') {   || $target eq 'edit') {
  ($result,$form_tag_start) =   ($result,$form_tag_start,$probpartlist) =
     &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,      &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,
  $name);   $name);
       } elsif (($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) {
           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 ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';}      if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';}
Line 1190  sub start_problem { Line 1674  sub start_problem {
  $target eq 'tex') {   $target eq 'tex') {
   
  #handle rand seed in construction space   #handle rand seed in construction space
  my $rndseed=&setup_rndseed($safeeval,$target);   my $rndseed=&setup_rndseed($safeeval,$target,$probpartlist);
           if (($target eq 'grade') && &Apache::response::submitted()) {
               if ($Apache::lonhomework::type eq 'randomizetry') {
                   $Apache::lonhomework::results{'resource.0.rawrndseed'}=$rndseed;
               } else {
                   my @parts;
                   if (ref($probpartlist) eq 'ARRAY') {
                       @parts = @{$probpartlist};
                   }
                   unless (@parts) {
                       $Apache::lonhomework::results{'resource.0.rawrndseed'}=$Apache::lonhomework::rawrndseed;
                   }
               }
           }
  my ($symb)=&Apache::lonnet::whichuser();   my ($symb)=&Apache::lonnet::whichuser();
   
  if ($env{'request.state'} ne "construct" &&    if ($env{'request.state'} ne "construct" && 
Line 1398  sub end_problem { Line 1895  sub end_problem {
  my $id = $Apache::inputtags::part;   my $id = $Apache::inputtags::part;
  my $weight = &Apache::lonnet::EXT("resource.$id.weight");   my $weight = &Apache::lonnet::EXT("resource.$id.weight");
  my $packages=&Apache::lonnet::metadata($env{'request.uri'},'packages');   my $packages=&Apache::lonnet::metadata($env{'request.uri'},'packages');
  my @packages = split /,/,$packages;   my @packages = split(/,/,$packages);
  my $allow_print_points = 0;   my $allow_print_points = 0;
  foreach my $partial_key (@packages) {   foreach my $partial_key (@packages) {
     if ($partial_key=~m/^part_0$/) {      if ($partial_key=~m/^part_0$/) {
Line 2057  sub end_while { Line 2554  sub end_while {
     }      }
     $return = &Apache::run::run($code,$safeeval);      $return = &Apache::run::run($code,$safeeval);
  }   }
  if ($error) {          if ($error) {
     &Apache::lonxml::error('<pre>'.&mt('Code ran too long. It ran for more than').' '.$Apache::lonnet::perlvar{'lonScriptTimeout'}.' '.&mt('seconds occurred while running &lt;while&gt; on line').' '.$line.'</pre>');              &Apache::lonxml::error(
  }                  '<pre>'
                  .&mt('Code ran too long. It ran for more than [_1] seconds.',
                           $Apache::lonnet::perlvar{'lonScriptTimeout'})
                  .&mt('This occurred while running &lt;while&gt; on line [_1].',
                           $line)
                  .'</pre>');
           }
     } elsif ($target eq "edit") {      } elsif ($target eq "edit") {
  $result.= &Apache::edit::tag_end($target,$token,'');   $result.= &Apache::edit::tag_end($target,$token,'');
     }      }
Line 2126  sub start_randomlist { Line 2629  sub start_randomlist {
                     }                      }
                 }                  }
             }              }
     for(0 .. $show) {      for my $i (0 .. $show) {
  $bodytext .= "$randomlist[ $idx_arr[$_] ]";   $bodytext .= "$randomlist[ $idx_arr[$i] ]";
     }      }
     &Apache::lonxml::newparser($parser,\$bodytext);      &Apache::lonxml::newparser($parser,\$bodytext);
  }   }
Line 2241  sub start_part { Line 2744  sub start_part {
     my $hidden=&Apache::loncommon::check_if_partid_hidden($Apache::inputtags::part);      my $hidden=&Apache::loncommon::check_if_partid_hidden($Apache::inputtags::part);
     my $newtype=&Apache::lonnet::EXT("resource.$id.type");      my $newtype=&Apache::lonnet::EXT("resource.$id.type");
     if ($newtype) { $Apache::lonhomework::type=$newtype; }      if ($newtype) { $Apache::lonhomework::type=$newtype; }
       if ($Apache::lonhomework::type eq 'randomizetry') {
           my $rndseed=&setup_rndseed($safeeval,$target);
           if (($target eq 'grade') && &Apache::response::submitted()) {
               $Apache::lonhomework::results{"resource.$id.rawrndseed"}=$rndseed;
           }
       } elsif (($target eq 'grade') && &Apache::response::submitted()) {
           $Apache::lonhomework::results{"resource.$id.rawrndseed"}=$Apache::lonhomework::rawrndseed;
       }
     my $in_order_show=&ordered_show_check();      my $in_order_show=&ordered_show_check();
     my $expression='$external::part=\''.$Apache::inputtags::part.'\';';      my $expression='$external::part=\''.$Apache::inputtags::part.'\';';
     $expression.='$external::type=\''.$Apache::lonhomework::type.'\';';      $expression.='$external::type=\''.$Apache::lonhomework::type.'\';';
Line 2291  sub start_part { Line 2802  sub start_part {
     }      }
     my $weight = &Apache::lonnet::EXT("resource.$id.weight");      my $weight = &Apache::lonnet::EXT("resource.$id.weight");
     my $allkeys=&Apache::lonnet::metadata($env{'request.uri'},'packages');      my $allkeys=&Apache::lonnet::metadata($env{'request.uri'},'packages');
     my @allkeys = split /,/,$allkeys;      my @allkeys = split(/,/,$allkeys);
     my $allow_print_points = 0;      my $allow_print_points = 0;
     foreach my $partial_key (@allkeys) {      foreach my $partial_key (@allkeys) {
  if ($partial_key=~m/^part_(.*)$/) {   if ($partial_key=~m/^part_(.*)$/) {
Line 2496  sub start_problemtype { Line 3007  sub start_problemtype {
     ['hide','Hide']]      ['hide','Hide']]
    ,$token);     ,$token);
  $result .=&Apache::edit::checked_arg('When used as type(s):','for',   $result .=&Apache::edit::checked_arg('When used as type(s):','for',
      [ ['exam','Exam/Quiz Problem'],       [ ['exam','Bubblesheet Exam/Quiz Problem'],
        ['survey','Survey'],         ['survey','Survey'],
                                                ['surveycred','Survey (with credit)'],                                                 ['surveycred','Survey (with credit)'],
                                                ['anonsurvey','Anonymous Survey'],                                                 ['anonsurvey','Anonymous Survey'],
Line 2539  sub end_startouttext { Line 3050  sub end_startouttext {
     if ($target eq 'edit') {      if ($target eq 'edit') {
  my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;   my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;
  $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);   $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);
  $result.=&Apache::edit::start_table($token)."<tr><td>".&mt('Text Block')."</td>"          $result.=&Apache::edit::start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button()
                    ." ".&mt('Text Block')."</td>"
                  .'<td><span class="LC_nobreak">'.&mt('Delete?').' '                   .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
                  .&Apache::edit::deletelist($target,$token)                   .&Apache::edit::deletelist($target,$token)
                  .'</span></td>'                   .'</span></td>'
          .'<td align="left"><span id="math_'.$areaid.'">'           .'<td><span id="math_'.$areaid.'">'
  .&Apache::lonhtmlcommon::dragmath_button($areaid,1)   .&Apache::lonhtmlcommon::dragmath_button($areaid,1)
  .'</span></td>'   .'</span></td>'
  .'<td>'   .'<td>'
  .&Apache::edit::insertlist($target,$token)   .&Apache::edit::insertlist($target,$token)
  .'</td>'   .'</td>'
          .'<td align="right" valign="top">' .           .'<td class="LC_edit_problem_latexhelper">' .
          &Apache::loncommon::helpLatexCheatsheet().           &Apache::loncommon::helpLatexCheatsheet().
  &Apache::edit::end_row().   &Apache::edit::end_row().
                  &Apache::edit::start_spanning_row()."\n".                   &Apache::edit::start_spanning_row()."\n".

Removed from v.1.512.2.3  
changed lines
  Added in v.1.528


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