--- 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- '.
&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?','
-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=
' ';
@@ -8238,7 +8309,7 @@ sub hand_bubble_option {
return &mt('The sequence to be graded contains response types which are handgraded.').''.&mt('List of CODES to validate against:').' '.
$env{'form.scantron_CODElist'}.'
').
' '.&mt('or').' '.
- '
- '.&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 { '
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.