--- loncom/homework/grades.pm 2024/12/09 22:01:01 1.800
+++ loncom/homework/grades.pm 2024/12/14 17:47:39 1.806
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# The LON-CAPA Grading handler
#
-# $Id: grades.pm,v 1.800 2024/12/09 22:01:01 raeburn Exp $
+# $Id: grades.pm,v 1.806 2024/12/14 17:47:39 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -1263,18 +1263,18 @@ sub do_passback {
my $cdom = $env{"course.$env{'request.course.id'}.domain"};
my $cnum = $env{"course.$env{'request.course.id'}.num"};
my $crstype = &Apache::loncommon::course_type();
- my ($launcher,$appname,$setter,$linkuri,$linkprotector,$scope,$chosen);
+ my ($launchsymb,$appname,$setter,$linkuri,$linkprotector,$scope,$chosen);
if ($env{'form.passback'} ne '') {
$chosen = &unescape($env{'form.passback'});
($linkuri,$linkprotector,$scope) = split("\0",$chosen);
- ($launcher,$appname,$setter) = &get_passback_launcher($cdom,$cnum,$chosen);
+ ($launchsymb,$appname,$setter) = &get_passback_launcher($cdom,$cnum,$chosen);
}
- if ($launcher ne '') {
- $request->print(&launcher_info_box($launcher,$appname,$setter,$linkuri,$scope));
+ if ($launchsymb ne '') {
+ $request->print(&launcher_info_box($launchsymb,$appname,$setter,$linkuri,$scope));
}
my $error;
if ($perm{'mgr'}) {
- if ($launcher ne '') {
+ if ($launchsymb ne '') {
my @poss_students = &Apache::loncommon::get_env_multiple('form.stuinfo');
if (@poss_students) {
my %possibles;
@@ -1312,12 +1312,11 @@ sub do_passback {
if ($lti_in_use->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
$scoretype = $1;
}
- my $pbsymb = &Apache::loncommon::symb_from_tinyurl($linkuri,$cnum,$cdom);
my $pbmap;
- if ($pbsymb =~ /\.(page|sequence)$/) {
- $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pbsymb))[2]);
+ if ($launchsymb =~ /\.(page|sequence)$/) {
+ $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($launchsymb))[2]);
} else {
- $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pbsymb))[0]);
+ $pbmap = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($launchsymb))[0]);
}
$pbmap = &Apache::lonnet::clutter($pbmap);
my $pbscope;
@@ -1332,13 +1331,13 @@ sub do_passback {
my $numstudents = scalar(keys(%tosend));
my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($request,$numstudents);
my $outcome = &Apache::loncommon::start_data_table().
- &Apache::loncommon::start_data_table_header_row();
+ &Apache::loncommon::start_data_table_header_row();
my $loop = 0;
while ($loop < 2) {
$outcome .= '
'.&mt('No.').' | '.
- ''.&nameUserString('header').' '.&mt('Section/Group').' | '.
- ''.&mt('Score').' | ';
- $loop++;
+ ''.&nameUserString('header').' '.&mt('Section/Group').' | '.
+ ''.&mt('Score').' | ';
+ $loop++;
}
$outcome .= &Apache::loncommon::end_data_table_header_row()."\n";
my $ctr=0;
@@ -1365,14 +1364,14 @@ sub do_passback {
$possible = 0;
my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom);
if (ref($navmap)) {
- my $res = $navmap->getBySymb($pbsymb);
+ my $res = $navmap->getBySymb($launchsymb);
if (ref($res)) {
my $partlist = $res->parts();
if (ref($partlist) eq 'ARRAY') {
- my %record = &Apache::lonnet::restore($pbsymb,$env{'request.course.id'},$udom,$uname);
+ my %record = &Apache::lonnet::restore($launchsymb,$env{'request.course.id'},$udom,$uname);
foreach my $part (@{$partlist}) {
next if ($record{"resource.$part.solved"} =~/^excused/);
- my $weight = &Apache::lonnet::EXT("resource.$part.weight",$pbsymb,$udom,$uname,$usec);
+ my $weight = &Apache::lonnet::EXT("resource.$part.weight",$launchsymb,$udom,$uname,$usec);
$possible += $weight;
if (($record{'version'}) && (exists($record{"resource.$part.awarded"}))) {
my $awarded = $record{"resource.$part.awarded"};
@@ -1386,7 +1385,7 @@ sub do_passback {
}
} elsif (($pbscope eq 'map') || ($pbscope eq 'nonrec')) {
($total,$possible) =
- &Apache::lonhomework::get_lti_score($uname,$udom,$pbmap,$pbscope);
+ &Apache::lonhomework::get_lti_score($uname,$udom,$usec,$pbmap,$pbscope);
}
if (($id ne '') && ($url ne '') && ($possible)) {
my ($sent,$score,$code,$result) =
@@ -1408,7 +1407,7 @@ sub do_passback {
'id' => $id,
'clientip' => $pb{'clientip'},
'whodoneit' => $env{'user.name'}.':'.$env{'user.domain'},
- };
+ };
my $value='';
foreach my $key (keys(%{$store})) {
$value.=&escape($key).'='.&Apache::lonnet::freeze_escape($store->{$key}).'&';
@@ -1420,12 +1419,11 @@ sub do_passback {
if ($ctr%2 ==1) {
$outcome .= &Apache::loncommon::start_data_table_row();
}
- my $section = $classlist->{$student}->[&Apache::loncoursedata::CL_SECTION()];
my $group = $classlist->{$student}->[&Apache::loncoursedata::CL_GROUP()];
$outcome .= ''.$ctr.' | '.
- ''.&nameUserString(undef,$$fullname{$student},$uname,$udom).
- ' '.$section.($group ne '' ?'/'.$group:'').' | '.
- ''.$score.' | '."\n";
+ ''.&nameUserString(undef,$$fullname{$student},$uname,$udom).
+ ' '.$usec.($group ne '' ?'/'.$group:'').' | '.
+ ''.$score.' | '."\n";
if ($ctr%2 ==0) {
$outcome .= &Apache::loncommon::end_data_table_row()."\n";
}
@@ -1441,27 +1439,31 @@ sub do_passback {
}
if ($no_passback) {
&Apache::lonnet::log($udom,$uname,$uhome,$no_passback." score: $score; total: $total; possible: $possible");
+ my $key = &Time::HiRes::time().':'.$uname.':'.$udom.':'.
+ "$linkuri\0$linkprotector\0$scope";
my $ltigrade = {
- 'ltinum' => $ltinum,
- 'lti' => $lti_in_use,
- 'crsdef' => $crsdef,
- 'cid' => $cdom.'_'.$cnum,
- 'uname' => $uname,
- 'udom' => $udom,
- 'uhome' => $uhome,
- 'pbid' => $id,
- 'pburl' => $url,
- 'pbtype' => $pb{'type'},
- 'pbscope' => $pbscope,
- 'pbmap' => $pbmap,
- 'pbsymb' => $pbsymb,
- 'format' => $scoretype,
- 'scope' => $scope,
- 'clientip' => $pb{'clientip'},
- 'linkprot' => $linkprotector.':'.$linkuri,
- 'total' => $total,
- 'possible' => $possible,
- 'score' => $score,
+ $key => {
+ 'ltinum' => $ltinum,
+ 'lti' => $lti_in_use,
+ 'crsdef' => $crsdef,
+ 'cid' => $cdom.'_'.$cnum,
+ 'uname' => $uname,
+ 'udom' => $udom,
+ 'uhome' => $uhome,
+ 'pbid' => $id,
+ 'pburl' => $url,
+ 'pbtype' => $pb{'type'},
+ 'pbscope' => $pbscope,
+ 'pbmap' => $pbmap,
+ 'pbsymb' => $launchsymb,
+ 'format' => $scoretype,
+ 'scope' => $scope,
+ 'clientip' => $pb{'clientip'},
+ 'linkprot' => $linkprotector.':'.$linkuri,
+ 'total' => $total,
+ 'possible' => $possible,
+ 'score' => $score,
+ },
};
&Apache::lonnet::put('linkprot_passback_pending',$ltigrade,$cdom,$cnum);
}
@@ -1575,31 +1577,27 @@ sub get_passback_launcher {
}
}
}
- if ($linkuri =~ m{^\Q/tiny/$cdom/\E(\w+)$}) {
- my $key = $1;
- my $tinyurl;
- my ($result,$cached)=&Apache::lonnet::is_cached_new('tiny',$cdom."\0".$key);
- if (defined($cached)) {
- $tinyurl = $result;
- } else {
- my $configuname = &Apache::lonnet::get_domainconfiguser($cdom);
- my %currtiny = &Apache::lonnet::get('tiny',[$key],$cdom,$configuname);
- if ($currtiny{$key} ne '') {
- $tinyurl = $currtiny{$key};
- &Apache::lonnet::do_cache_new('tiny',$cdom."\0".$key,$currtiny{$key},600);
- }
- }
- if ($tinyurl) {
- my ($crsnum,$launchsymb) = split(/\&/,$tinyurl);
- if ($crsnum eq $cnum) {
- my %passback = &Apache::lonnet::get('nohist_linkprot_passback',[$launchsymb],$cdom,$cnum);
- if (ref($passback{$launchsymb}) eq 'HASH') {
- if (exists($passback{$launchsymb}{$chosen})) {
- return ($launchsymb,$appname,$setter);
- }
+ my $launchsymb = &Apache::loncommon::symb_from_tinyurl($linkuri,$cnum,$cdom);
+ if ($launchsymb eq '') {
+ my %passback = &Apache::lonnet::dump('nohist_linkprot_passback',$cdom,$cnum);
+ foreach my $poss_symb (keys(%passback)) {
+ if (ref($passback{$poss_symb}) eq 'HASH') {
+ if (exists($passback{$poss_symb}{$chosen})) {
+ $launchsymb = $poss_symb;
+ last;
}
}
}
+ if ($launchsymb ne '') {
+ return ($launchsymb,$appname,$setter);
+ }
+ } else {
+ my %passback = &Apache::lonnet::get('nohist_linkprot_passback',[$launchsymb],$cdom,$cnum);
+ if (ref($passback{$launchsymb}) eq 'HASH') {
+ if (exists($passback{$launchsymb}{$chosen})) {
+ return ($launchsymb,$appname,$setter);
+ }
+ }
}
return ();
}
@@ -1679,7 +1677,7 @@ sub passbacks_for_symb {
}
if (ref($passback{$symb}) eq 'HASH') {
foreach my $launcher (keys(%{$passback{$symb}})) {
- $needpb{$launcher} = 1;
+ $needpb{$launcher} = $symb;
}
}
}
@@ -1696,7 +1694,7 @@ sub passbacks_for_symb {
}
if (ref($passback{$mapsymb}) eq 'HASH') {
foreach my $launcher (keys(%{$passback{$mapsymb}})) {
- $needpb{$launcher} = 1;
+ $needpb{$launcher} = $mapsymb;
}
}
}
@@ -1713,7 +1711,7 @@ sub passbacks_for_symb {
foreach my $launcher (keys(%{$passback{$key}})) {
my ($linkuri,$linkprotector,$scope) = split("\0",$launcher);
next unless ($scope eq 'rec');
- $needpb{$launcher} = 1;
+ $needpb{$launcher} = $key;
}
}
}
@@ -1726,7 +1724,7 @@ sub passbacks_for_symb {
}
sub process_passbacks {
- my ($context,$symbs,$cdom,$cnum,$udom,$uname,$weights,$awardeds,$excuseds,$needpb,
+ my ($context,$symbs,$cdom,$cnum,$udom,$uname,$usec,$weights,$awardeds,$excuseds,$needpb,
$skip_passback,$pbsave,$pbids) = @_;
if ((ref($needpb) eq 'HASH') && (ref($skip_passback) eq 'HASH') && (ref($pbsave) eq 'HASH')) {
my (%weight,%awarded,%excused);
@@ -1778,7 +1776,7 @@ sub process_passbacks {
if ($pb{'lti_in_use'}->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
$pb{'scoretype'} = $1;
}
- $pb{'symb'} = &Apache::loncommon::symb_from_tinyurl($pb{'linkuri'},$cnum,$cdom);
+ $pb{'symb'} = $needpb->{$launcher};
if ($pb{'symb'} =~ /\.(page|sequence)$/) {
$pb{'map'} = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($pb{'symb'}))[2]);
} else {
@@ -1827,6 +1825,7 @@ sub process_passbacks {
'uname' => $uname,
'udom' => $udom,
'uhome' => $uhome,
+ 'usec' => $usec,
'pbid' => $pbid,
'pburl' => $pburl,
'pbtype' => $pb{'type'},
@@ -1840,7 +1839,7 @@ sub process_passbacks {
'total_s' => \%total_by_symb,
'possible_s' => \%possible_by_symb,
};
- push(@Apache::lonhomework::ltipassback,$ltigrade);
+ push(@Apache::grades::ltipassback,$ltigrade);
next;
}
my ($total,$possible);
@@ -1849,7 +1848,7 @@ sub process_passbacks {
$possible = $possible_by_symb{$pb{'symb'}};
} elsif (($pb{'pbscope'} eq 'map') || ($pb{'pbscope'} eq 'nonrec')) {
($total,$possible) =
- &Apache::lonhomework::get_lti_score($uname,$udom,$pb{'map'},$pb{'pbscope'},
+ &Apache::lonhomework::get_lti_score($uname,$udom,$usec,$pb{'map'},$pb{'pbscope'},
\%total_by_symb,\%possible_by_symb);
}
if (!$possible) {
@@ -4240,18 +4239,20 @@ sub processHandGrade {
foreach my $collabstr (@collabstrs) {
my ($part,@collaborators) = split(/:/,$collabstr);
foreach my $collaborator (@collaborators) {
- my ($errorflag,$pts,$wgt) =
+ my ($errorflag,$pts,$wgt,$numchg,$numupdate) =
&saveHandGrade($request,$symb,$collaborator,$udom,$ctr,
- $env{'form.unamedom'.$ctr},$part,\%queueable,\%needpb,\%skip_passback,%pbsave);
+ $env{'form.unamedom'.$ctr},$part,\%queueable);
if ($errorflag eq 'not_allowed') {
$request->print("".&mt('Not allowed to modify grades for [_1]',"$collaborator:$udom")."");
next;
} else {
- $pbcollab{$collaborator}{$part} = [$pts,$wgt];
+ if ($numchg || $numupdate) {
+ $pbcollab{$collaborator}{$part} = [$pts,$wgt];
+ }
if ($message ne '') {
my ($baseurl,$showsymb) =
&get_feedurl_and_symb($symb,$collaborator,
- $udom);
+ $udom);
if ($env{'form.withgrades'.$ctr}) {
$messagetail = " for $restitle";
@@ -4266,7 +4267,48 @@ sub processHandGrade {
$ctr++;
}
if ((keys(%pbcollab)) && (keys(%needpb))) {
- # FIXME passback scores for collaborators
+ foreach my $user (keys(%pbcollab)) {
+ my ($clbuname,$clbudom) = split(/:/,$user);
+ my $clbusec = &Apache::lonnet::getsection($clbudom,$clbuname,$cdom.'_'.$cnum);
+ if (ref($pbcollab{$user}) eq 'HASH') {
+ my @clparts = keys(%{$pbcollab{$user}});
+ if (@clparts) {
+ my $navmap = Apache::lonnavmaps::navmap->new($clbuname,$clbudom,$clbusec);
+ if (ref($navmap)) {
+ my $res = $navmap->getBySymb($symb);
+ if (ref($res)) {
+ my $partlist = $res->parts();
+ if (ref($partlist) eq 'ARRAY') {
+ my (%weights,%awardeds,%excuseds);
+ foreach my $part (@{$partlist}) {
+ if ($res->status($part) eq $res->EXCUSED) {
+ $excuseds{$symb}{$part} = 1;
+ } else {
+ $excuseds{$symb}{$part} = '';
+ }
+ if ((exists($pbcollab{$user}{$part})) && (ref($pbcollab{$user}{$part}) eq 'ARRAY')) {
+ my $pts = $pbcollab{$user}{$part}[0];
+ my $wt = $pbcollab{$user}{$part}[1];
+ if ($wt) {
+ $awardeds{$symb}{$part} = $pts/$wt;
+ $weights{$symb}{$part} = $wt;
+ } else {
+ $awardeds{$symb}{$part} = 0;
+ $weights{$symb}{$part} = 0;
+ }
+ } else {
+ $awardeds{$symb}{$part} = $res->awarded($part);
+ $weights{$symb}{$part} = $res->weight($part);
+ }
+ }
+ &process_passbacks('handgrade',[$symb],$cdom,$cnum,$clbudom,$clbuname,$clbusec,\%weights,
+ \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
+ }
+ }
+ }
+ }
+ }
+ }
}
}
@@ -4429,22 +4471,18 @@ sub saveHandGrade {
my %record = &Apache::lonnet::restore($symb,$env{'request.course.id'},$domain,$stuname);
my @parts_graded;
my %newrecord = ();
- my ($pts,$wgt,$totchg) = ('','',0);
+ my ($pts,$wgt,$totchg,$sendupdate) = ('','',0,0);
my %aggregate = ();
my $aggregateflag = 0;
- my $sendupdate;
if ($env{'form.HIDE'.$newflg}) {
my ($version,$parts) = split(/:/,$env{'form.HIDE'.$newflg},2);
my $numchgs = &makehidden($version,$parts,\%record,$symb,$domain,$stuname,1);
$totchg += $numchgs;
- if ($numchgs) {
- $sendupdate = 1;
- }
}
my (%weights,%awardeds,%excuseds);
my @parts = split(/:/,$env{'form.partlist'.$newflg});
foreach my $new_part (@parts) {
- #collaborator ($submi may vary for different parts
+ #collaborator ($submitter may vary for different parts)
if ($submitter && $new_part ne $part) { next; }
my $dropMenu = $env{'form.GD_SEL'.$newflg.'_'.$new_part};
if ($env{'form.WGT'.$newflg.'_'.$new_part} eq '') {
@@ -4461,7 +4499,7 @@ sub saveHandGrade {
$newrecord{'resource.'.$new_part.'.awarded'} = '';
}
$newrecord{'resource.'.$new_part.'.regrader'}="$env{'user.name'}:$env{'user.domain'}";
- $sendupdate = 1;
+ $sendupdate ++;
}
} elsif ($dropMenu eq 'reset status'
&& exists($record{'resource.'.$new_part.'.solved'})) { #don't bother if no old records -> no attempts
@@ -4485,7 +4523,7 @@ sub saveHandGrade {
&decrement_aggs($symb,$new_part,\%aggregate,$aggtries,$totaltries,$solvedstatus);
$aggregateflag = 1;
}
- $sendupdate = 1;
+ $sendupdate ++;
$excuseds{$symb}{$new_part} = '';
$awardeds{$symb}{$new_part} = '';
} elsif ($dropMenu eq '') {
@@ -4506,7 +4544,7 @@ sub saveHandGrade {
next;
} else {
push(@parts_graded,$new_part);
- $sendupdate = 1;
+ $sendupdate ++;
}
if ($record{'resource.'.$new_part.'.awarded'} ne $partial) {
$newrecord{'resource.'.$new_part.'.awarded'} = $partial;
@@ -4558,14 +4596,14 @@ sub saveHandGrade {
&Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
$cdom,$cnum);
}
- if (($sendupdate) && (!$submitter)) {
+ if (($sendupdate || $totchg) && (!$submitter)) {
if ((ref($needpb) eq 'HASH') &&
(keys(%{$needpb}))) {
- &process_passbacks('handgrade',[$symb],$cdom,$cnum,$domain,$stuname,\%weights,
+ &process_passbacks('handgrade',[$symb],$cdom,$cnum,$domain,$stuname,$usec,\%weights,
\%awardeds,\%excuseds,$needpb,$skip_passback,$pbsave);
}
}
- return ('',$pts,$wgt,$totchg);
+ return ('',$pts,$wgt,$totchg,$sendupdate);
}
sub makehidden {
@@ -5650,7 +5688,7 @@ sub editgrades {
$updateCtr++;
if (keys(%needpb)) {
$weights{$symb} = \%weight;
- &process_passbacks('editgrades',[$symb],$cdom,$cnum,$udom,$uname,\%weights,
+ &process_passbacks('editgrades',[$symb],$cdom,$cnum,$udom,$uname,$usec,\%weights,
\%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
}
} else {
@@ -6179,7 +6217,7 @@ sub csvuploadassign {
$request->print('.');
# Remove from grading queue
&Apache::bridgetask::remove_from_queue('gradingqueue',$symb,$cdom,$cnum,
- $domain,$username);
+ $domain,$username);
$countdone++;
if ($passback) {
my @parts_in_upload;
@@ -6201,7 +6239,7 @@ sub csvuploadassign {
$awardeds{$symb}{$part} = $record{"resource.$part.awarded"};
}
}
- &process_passbacks('csvupload',[$symb],$cdom,$cnum,$domain,$username,\%weights,
+ &process_passbacks('csvupload',[$symb],$cdom,$cnum,$domain,$username,$usec,\%weights,
\%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
}
} else {
@@ -6952,7 +6990,6 @@ sub updateGradeByPage {
$request->print($hidemsg.$grademsg.$studentTable);
if (@updates) {
- undef(@Apache::lonhomework::ltipassback);
my (@allsymbs,$mapsymb,@recurseup,%parentmapsymbs,%possmappb,%possrespb);
@allsymbs = @updates;
if (ref($map)) {
@@ -6965,13 +7002,14 @@ sub updateGradeByPage {
map { $parentmapsymbs{$_} = 1; } @recurseup;
}
my %passback = &Apache::lonnet::get('nohist_linkprot_passback',\@allsymbs,$cdom,$cnum);
- my (%uniqsymbs,$use_symbs_in_map);
+ my (%uniqsymbs,$use_symbs_in_map,%launch_to_symb);
if (keys(%passback)) {
foreach my $possible (keys(%passback)) {
if (ref($passback{$possible}) eq 'HASH') {
if ($possible eq $mapsymb) {
foreach my $launcher (keys(%{$passback{$possible}})) {
$possmappb{$launcher} = 1;
+ $launch_to_symb{$launcher} = $possible;
}
$use_symbs_in_map = 1;
} elsif (exists($parentmapsymbs{$possible})) {
@@ -6980,11 +7018,13 @@ sub updateGradeByPage {
if ($scope eq 'rec') {
$possmappb{$launcher} = 1;
$use_symbs_in_map = 1;
+ $launch_to_symb{$launcher} = $possible;
}
}
} elsif (grep(/^\Q$possible$\E$/,@updates)) {
foreach my $launcher (keys(%{$passback{$possible}})) {
$possrespb{$launcher} = 1;
+ $launch_to_symb{$launcher} = $possible;
}
$uniqsymbs{$possible} = 1;
}
@@ -7006,17 +7046,20 @@ sub updateGradeByPage {
my %pbids = &Apache::lonnet::get('nohist_'.$cdom.'_'.$cnum.'_linkprot_pb',\@posslaunchers,$udom,$uname);
foreach my $key (keys(%pbids)) {
if (ref($pbids{$key}) eq 'ARRAY') {
- $needpb{$key} = 1;
+ if ($launch_to_symb{$key}) {
+ $needpb{$key} = $launch_to_symb{$key};
+ }
}
}
my @symbs = keys(%uniqsymbs);
- &process_passbacks('updatebypage',\@symbs,$cdom,$cnum,$udom,$uname,\%weights,
+ &process_passbacks('updatebypage',\@symbs,$cdom,$cnum,$udom,$uname,$usec,\%weights,
\%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave,\%pbids);
- if (@Apache::lonhomework::ltipassback) {
+ if (@Apache::grades::ltipassback) {
unless ($registered_cleanup) {
my $handlers = $request->get_handlers('PerlCleanupHandler');
$request->set_handlers('PerlCleanupHandler' =>
- [\&Apache::lonhomework::do_ltipassback,@{$handlers}]);
+ [\&Apache::grades::make_passback,@{$handlers}]);
+ $registered_cleanup=1;
}
}
}
@@ -7024,6 +7067,17 @@ sub updateGradeByPage {
return '';
}
+sub make_passback {
+ if (@Apache::grades::ltipassback) {
+ my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
+ my $ip = &Apache::lonnet::get_host_ip($lonhost);
+ foreach my $item (@Apache::grades::ltipassback) {
+ &Apache::lonhomework::run_passback($item,$lonhost,$ip);
+ }
+ undef(@Apache::grades::ltipassback);
+ }
+}
+
#-------- end of section for handling grading by page/sequence ---------
#
#-------------------------------------------------------------------
@@ -12540,6 +12594,10 @@ sub assign_clicker_grades {
if ($res_error) {
return &navmap_errormsg();
}
+ my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my %needpb = &passbacks_for_symb($cdom,$cnum,$symb);
+ my (%skip_passback,%pbsave);
# FIXME: This should probably look for the first handgradeable part
my $part=$$partlist[0];
# Start screen output
@@ -12649,7 +12707,15 @@ sub assign_clicker_grades {
$result.="
Failed to save student $username:$domain. Message when trying to save was ($returncode)";
} else {
$storecount++;
- #FIXME Do passback for $user if required
+ if (keys(%needpb)) {
+ my (%weights,%awardeds,%excuseds);
+ my $usec = &Apache::lonnet::getsection($domain,$username,$env{'request.course.id'});
+ $weights{$symb}{$part} = &Apache::lonnet::EXT("resource.$part.weight",$symb,$domain,$username,$usec);
+ $awardeds{$symb}{$part} = $ave;
+ $excuseds{$symb}{$part} = '';
+ &process_passbacks('clickergrade',[$symb],$cdom,$cnum,$domain,$username,$usec,\%weights,
+ \%awardeds,\%excuseds,\%needpb,\%skip_passback,\%pbsave);
+ }
}
}
}
@@ -12808,6 +12874,10 @@ sub handler {
&Apache::lonnet::logthis("grades got multiple commands ".join(':',@commands));
}
+# -------------------------------------- Flag and buffer for registered cleanup
+ $registered_cleanup=0;
+ undef(@Apache::grades::ltipassback);
+
# see what the symb is
my $symb=$env{'form.symb'};