--- loncom/homework/grades.pm 2014/02/05 15:09:30 1.719 +++ loncom/homework/grades.pm 2014/11/21 17:59:11 1.727 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # The LON-CAPA Grading handler # -# $Id: grades.pm,v 1.719 2014/02/05 15:09:30 bisitz Exp $ +# $Id: grades.pm,v 1.727 2014/11/21 17:59:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -330,6 +330,8 @@ sub cleanRecord { my $grayFont = ''; if ($response =~ /^(option|rank)$/) { my %answer=&Apache::lonnet::str2hash($answer); + my @answer = %answer; + %answer = map {&HTML::Entities::encode($_, '"<>&')} @answer; my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"}); my ($toprow,$bottomrow); foreach my $foil (@$order) { @@ -346,6 +348,8 @@ sub cleanRecord { $bottomrow.''; } elsif ($response eq 'match') { my %answer=&Apache::lonnet::str2hash($answer); + my @answer = %answer; + %answer = map {&HTML::Entities::encode($_, '"<>&')} @answer; my %grading=&Apache::lonnet::str2hash($record->{$version."resource.$partid.$respid.submissiongrading"}); my @items=&Apache::lonnet::str2array($record->{$version."resource.$partid.$respid.submissionitems"}); my ($toprow,$middlerow,$bottomrow); @@ -368,6 +372,8 @@ sub cleanRecord { $bottomrow.''; } elsif ($response eq 'radiobutton') { my %answer=&Apache::lonnet::str2hash($answer); + my @answer = %answer; + %answer = map {&HTML::Entities::encode($_, '"<>&')} @answer; my ($toprow,$bottomrow); my $correct = &get_radiobutton_correct_foil($partid,$respid,$symb,$uname,$udom,$type,$trial,$rndseed); @@ -400,10 +406,11 @@ sub cleanRecord { $env{'form.kwstyle'} = $keyhash{$loginuser.'_kwstyle'} ne '' ? $keyhash{$loginuser.'_kwstyle'} : ''; $env{'form.'.$symb} = 1; # so that we don't have to read it from disk for multiple sub of the same prob. } - $answer =~ s-\n-
-g; - return '

'.&keywords_highlight($answer).'
'; + return '

'.&keywords_highlight(&HTML::Entities::encode($answer, '"<>&')).'
'; + } elsif ( $response eq 'organic') { - my $result='Smile representation: "'.$answer.'"'; + my $result=&mt('Smile representation: [_1]', + '"'.&HTML::Entities::encode($answer, '"<>&').'"'); my $jme=$record->{$version."resource.$partid.$respid.molecule"}; $result.=&Apache::chemresponse::jme_img($jme,$answer,400); return $result; @@ -442,8 +449,9 @@ sub cleanRecord { $answer = &Apache::loncommon::format_previous_attempt_value('submission', $answer); + return $answer; } - return $answer; + return &HTML::Entities::encode($answer, '"<>&'); } #-- A couple of common js functions @@ -1287,10 +1295,8 @@ sub sub_page_js { } } } - } } - } formname.submit(); } @@ -2218,7 +2224,7 @@ sub submission { foreach my $submission (@$string) { my ($partid,$respid) = ($submission =~ /^resource\.([^\.]*)\.([^\.]*)\.submission/); if (join('_',@{$part}) ne ($partid.'_'.$respid)) { next; } - my ($ressub,$hide,$subval) = split(/:/,$submission,3); + my ($ressub,$hide,$draft,$subval) = split(/:/,$submission,4); # Similarity check my $similar=''; my ($type,$trial,$rndseed); @@ -2287,9 +2293,17 @@ sub submission { if ($hide eq 'anon') { $lastsubonly.='
'.&mt('Anonymous Survey').''; } else { - $lastsubonly.='
'.&mt('Submitted Answer:').' '. + $lastsubonly.='
'.&mt('Submitted Answer:').' '; + if ($draft) { + $lastsubonly.= ' '.&mt('Draft Copy').''; + } + $subval = &cleanRecord($subval,$responsetype,$symb,$partid, $respid,\%record,$order,undef,$uname,$udom,$type,$trial,$rndseed); + if ($responsetype eq 'essay') { + $subval =~ s{\n}{
}g; + } + $lastsubonly.=$subval."\n"; } if ($similar) {$lastsubonly.="

$similar\n";} $lastsubonly.=''; @@ -2302,12 +2316,15 @@ sub submission { if ($env{'form.lastSub'} eq 'datesub') { my ($parts,$handgrade,$responseType) = &response_type($symb,\$res_error); $request->print(&displaySubByDates($symb,\%record,$parts,$responseType,$checkIcon,$uname,$udom)); + } if ($env{'form.lastSub'} =~ /^(last|all)$/) { + my $identifier = (&canmodify($usec)? $counter : ''); $request->print(&Apache::loncommon::get_previous_attempt($symb,$uname,$udom, $env{'request.course.id'}, $last,'.submission', - 'Apache::grades::keywords_highlight')); + 'Apache::grades::keywords_highlight', + $usec,$identifier)); } $request->print(''."\n"); @@ -2535,10 +2552,8 @@ sub get_last_submission { } } my ($partid,$foo) = split(/submission$/,$key); - my $draft = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ? - ''.&mt('Draft Copy').' ' : ''; - #push(@string, join(':', $key, $hide, $draft.$lasthash{$key})); - push(@string, join(':', $key, $hide, $draft.( + my $draft = $lasthash{$partid.'awarddetail'} eq 'DRAFT' ? 1 : 0; + push(@string, join(':', $key, $hide, $draft, ( ref($lasthash{$key}) eq 'ARRAY' ? join(',', @{$lasthash{$key}}) : $lasthash{$key}) )); } @@ -2759,16 +2774,26 @@ sub processHandGrade { my $ctr = 0; while ($ctr < $ngrade) { my ($uname,$udom) = split(/:/,$env{'form.unamedom'.$ctr}); - my ($errorflag,$pts,$wgt) = &saveHandGrade($request,$symb,$uname,$udom,$ctr); + my ($errorflag,$pts,$wgt,$numhidden) = + &saveHandGrade($request,$symb,$uname,$udom,$ctr); if ($errorflag eq 'no_score') { $ctr++; next; } if ($errorflag eq 'not_allowed') { - $request->print("Not allowed to modify grades for $uname:$udom"); + $request->print( + '' + .&mt('Not allowed to modify grades for [_1]',"$uname:$udom") + .''); $ctr++; next; } + if ($numhidden) { + $request->print( + '' + .&mt('For [_1]: [quant,_2,transaction] hidden',"$uname:$udom",$numhidden) + .'
'); + } my $includemsg = $env{'form.includemsg'.$ctr}; my ($subject,$message,$msgstatus) = ('','',''); my $restitle = &Apache::lonnet::gettitle($symb); @@ -2990,9 +3015,14 @@ sub saveHandGrade { my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname); my @parts_graded; my %newrecord = (); - my ($pts,$wgt) = ('',''); + my ($pts,$wgt,$totchg) = ('','',0); my %aggregate = (); my $aggregateflag = 0; + if ($env{'form.HIDE'.$newflg}) { + my ($version,$parts) = split(/:/,$env{'form.HIDE'.$newflg},2); + my $numchgs = &makehidden($version,$parts,\%record,$symb,$domain,$stuname); + $totchg += $numchgs; + } my @parts = split(/:/,$env{'form.partlist'.$newflg}); foreach my $new_part (@parts) { #collaborator ($submi may vary for different parts @@ -3095,7 +3125,37 @@ sub saveHandGrade { &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate, $cdom,$cnum); } - return ('',$pts,$wgt); + return ('',$pts,$wgt,$totchg); +} + +sub makehidden { + my ($version,$parts,$record,$symb,$domain,$stuname) = @_; + return unless (ref($record) eq 'HASH'); + my %modified; + my $numchanged = 0; + if (exists($record->{$version.':keys'})) { + my $partsregexp = $parts; + $partsregexp =~ s/,/|/g; + foreach my $key (split(/\:/,$record->{$version.':keys'})) { + if ($key =~ /^resource\.(?:$partsregexp)\.([^\.]+)$/) { + my $item = $1; + unless (($item eq 'solved') || ($item =~ /^award(|msg|ed)$/)) { + $modified{$key} = $record->{$version.':'.$key}; + } + } elsif ($key =~ m{^(resource\.(?:$partsregexp)\.[^\.]+\.)(.+)$}) { + $modified{$1.'hidden'.$2} = $record->{$version.':'.$key}; + } elsif ($key =~ /^(ip|timestamp|host)$/) { + $modified{$key} = $record->{$version.':'.$key}; + } + } + if (keys(%modified)) { + if (&Apache::lonnet::putstore($env{'request.course.id'},$symb,$version,\%modified, + $domain,$stuname) eq 'ok') { + $numchanged ++; + } + } + } + return $numchanged; } sub check_and_remove_from_queue { @@ -4763,9 +4823,11 @@ sub displayPage { } } elsif ($env{'form.lastSub'} eq 'all') { my $last = ($env{'form.lastSub'} eq 'last' ? 'last' : ''); + my $identifier = (&canmodify($usec)? $prob : ''); $studentTable.=&Apache::loncommon::get_previous_attempt($symbx,$uname,$udom, $env{'request.course.id'}, - '','.submission'); + '','.submission',undef, + $usec,$identifier); } if (&canmodify($usec)) { @@ -4978,7 +5040,7 @@ sub updateGradeByPage { $iterator->next(); # skip the first BEGIN_MAP my $curRes = $iterator->next(); # for "current resource" - my ($depth,$question,$prob,$changeflag)= (1,1,1,0); + my ($depth,$question,$prob,$changeflag,$hideflag)= (1,1,1,0,0); while ($depth > 0) { if($curRes == $iterator->BEGIN_MAP) { $depth++; } if($curRes == $iterator->END_MAP) { $depth--; } @@ -4999,6 +5061,12 @@ sub updateGradeByPage { my @displayPts=(); my %aggregate = (); my $aggregateflag = 0; + if ($env{'form.HIDE'.$prob}) { + my %record = &Apache::lonnet::restore($symbx,$env{'request.course.id'},$udom,$uname); + my ($version,$parts) = split(/:/,$env{'form.HIDE'.$prob},2); + my $numchgs = &makehidden($version,$parts,\%record,$symbx,$udom,$uname); + $hideflag += $numchgs; + } foreach my $partid (@{$parts}) { my $newpts = $env{'form.GD_BOX'.$question.'_'.$partid}; my $oldpts = $env{'form.oldpts'.$question.'_'.$partid}; @@ -5089,8 +5157,11 @@ sub updateGradeByPage { $studentTable.=&Apache::loncommon::end_data_table(); my $grademsg=($changeflag == 0 ? &mt('No score was changed or updated.') : &mt('The scores were changed for [quant,_1,problem].', - $changeflag)); - $request->print($grademsg.$studentTable); + $changeflag).'
'); + my $hidemsg=($hideflag == 0 ? '' : + &mt('Submissions were marked "hidden" for [quant,_1,transaction].', + $hideflag).'
'); + $request->print($hidemsg.$grademsg.$studentTable); return ''; } @@ -6605,7 +6676,7 @@ sub scantron_warning_screen { $scantron_config{'CODEstart'} && $scantron_config{'CODElength'}) { $CODElist=$env{'form.scantron_CODElist'}; - if ($env{'form.scantron_CODElist'} eq '') { $CODElist='None'; } + if ($env{'form.scantron_CODElist'} eq '') { $CODElist=''.&mt('None').''; } $CODElist= ''.&mt('List of CODES to validate against:').''. $env{'form.scantron_CODElist'}.''; @@ -8238,7 +8309,7 @@ sub hand_bubble_option { return &mt('The sequence to be graded contains response types which are handgraded.').'

'. &mt('If you have already graded these by bubbling sheets to indicate points awarded, [_1]what point value is assigned to a filled last bubble in each row?','
'). ' '.&mt('or').' '. - '

'; + '

'; } return; } @@ -8901,7 +8972,7 @@ sub scantron_download_scantron_data { &Apache::lonnet::allowuploaded('/adm/grades',$skipped); $r->print('

- '.&mt('[_1]Original[_2] file as uploaded by the bubblesheet office.', + '.&mt('[_1]Original[_2] file as uploaded by the bubblesheet scanning office.', '','').'

@@ -9072,14 +9143,14 @@ sub checkscantron_results { ''.&mt('Bubblesheet').''.$showscandata.''.$last.''.$pid.''."\n". ''."\n". ''."\n". -'Submissions'.$showrecord.''."\n"; +''.&mt('Submissions').''.$showrecord.''."\n"; $passed ++; } else { my $css_class = ($failed % 2)?'LC_odd_row':'LC_even_row'; $badstudents .= ''.&mt('Bubblesheet').''.$scandata{$pid}.''.$last.''.$pid.''."\n". ''."\n". ''."\n". -'Submissions'.$record{$pid}.''."\n". +''.&mt('Submissions').''.$record{$pid}.''."\n". ''."\n"; $failed ++; } 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.