version 1.366, 2016/09/20 19:28:08
|
version 1.371, 2018/05/15 04:59:14
|
Line 53 use Apache::loncapamath();
|
Line 53 use Apache::loncapamath();
|
use Apache::Constants qw(:common); |
use Apache::Constants qw(:common); |
use Apache::loncommon(); |
use Apache::loncommon(); |
use Apache::lonparmset(); |
use Apache::lonparmset(); |
|
use Apache::lonnavmaps(); |
use Apache::lonlocal; |
use Apache::lonlocal; |
|
use LONCAPA qw(:DEFAULT :match); |
|
use LONCAPA::ltiutils(); |
use Time::HiRes qw( gettimeofday tv_interval ); |
use Time::HiRes qw( gettimeofday tv_interval ); |
use HTML::Entities(); |
use HTML::Entities(); |
use File::Copy(); |
use File::Copy(); |
|
|
# FIXME - improve commenting |
# FIXME - improve commenting |
|
|
|
my $registered_cleanup; |
|
|
BEGIN { |
BEGIN { |
&Apache::lonxml::register_insert(); |
&Apache::lonxml::register_insert(); |
Line 190 sub proctor_checked_in {
|
Line 194 sub proctor_checked_in {
|
if ($type eq 'Task') { |
if ($type eq 'Task') { |
my $version=$Apache::lonhomework::history{'resource.0.version'}; |
my $version=$Apache::lonhomework::history{'resource.0.version'}; |
$key ="resource.$version.0.checkedin"; |
$key ="resource.$version.0.checkedin"; |
} elsif ($type eq 'problem') { |
} elsif (($type eq 'problem') || ($type eq 'tool')) { |
$key ='resource.0.checkedin'; |
$key ='resource.0.checkedin'; |
} |
} |
# backward compatability, used to be username@domain, |
# backward compatability, used to be username@domain, |
Line 205 sub proctor_checked_in {
|
Line 209 sub proctor_checked_in {
|
return 1; |
return 1; |
} |
} |
} |
} |
|
|
return 0; |
return 0; |
} |
} |
|
|
Line 214 sub check_slot_access {
|
Line 217 sub check_slot_access {
|
|
|
# does it pass normal muster |
# does it pass normal muster |
my ($status,$datemsg)=&check_access($id,$symb); |
my ($status,$datemsg)=&check_access($id,$symb); |
|
|
my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb); |
my $useslots = &Apache::lonnet::EXT("resource.0.useslots",$symb); |
if ($useslots ne 'resource' && $useslots ne 'map' |
if ($useslots ne 'resource' && $useslots ne 'map' |
&& $useslots ne 'map_map') { |
&& $useslots ne 'map_map') { |
Line 350 sub check_slot_access {
|
Line 353 sub check_slot_access {
|
$is_correct = |
$is_correct = |
($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass' |
($Apache::lonhomework::history{"resource.$version.0.status"} eq 'pass' |
|| $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ ); |
|| $Apache::lonhomework::history{"resource.0.solved"} =~ /^correct_/ ); |
} elsif ($type eq 'problem') { |
} elsif (($type eq 'problem') || ($type eq 'tool')) { |
if ((ref($partlist) eq 'ARRAY') && (@{$partlist} > 0)) { |
if ((ref($partlist) eq 'ARRAY') && (@{$partlist} > 0)) { |
my ($numcorrect,$numgraded) = (0,0); |
my ($numcorrect,$numgraded) = (0,0); |
foreach my $part (@{$partlist}) { |
foreach my $part (@{$partlist}) { |
Line 410 sub check_slot_access {
|
Line 413 sub check_slot_access {
|
# used to gain access to it to work on it, until the due date is reached, and the |
# used to gain access to it to work on it, until the due date is reached, and the |
# problem then becomes CLOSED. Therefore return the slotstatus - |
# problem then becomes CLOSED. Therefore return the slotstatus - |
# (which will be one of: NOT_IN_A_SLOT, RESERVABLE, RESERVABLE_LATER, or NOTRESERVABLE). |
# (which will be one of: NOT_IN_A_SLOT, RESERVABLE, RESERVABLE_LATER, or NOTRESERVABLE). |
if (!defined($slot_name) && $type eq 'problem') { |
|
|
if (!defined($slot_name) && (($type eq 'problem') || ($type eq 'tool'))) { |
if ($slotstatus eq 'NOT_IN_A_SLOT') { |
if ($slotstatus eq 'NOT_IN_A_SLOT') { |
if (!$num_usable_slots) { |
if (!$num_usable_slots) { |
if ($env{'request.course.id'}) { |
($slotstatus,$datemsg) = &check_reservable_slot($slotstatus,$symb,$now,$checkedin, |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
$consumed_uniq); |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
unless ($symb) { |
|
($symb)=&Apache::lonnet::whichuser(); |
|
} |
|
$slotstatus = 'NOTRESERVABLE'; |
|
my ($reservable_now_order,$reservable_now,$reservable_future_order, |
|
$reservable_future) = |
|
&Apache::loncommon::get_future_slots($cnum,$cdom,$now,$symb); |
|
if ((ref($reservable_now_order) eq 'ARRAY') && (ref($reservable_now) eq 'HASH')) { |
|
if (@{$reservable_now_order} > 0) { |
|
if ((!$checkedin) || (ref($consumed_uniq) ne 'ARRAY')) { |
|
$slotstatus = 'RESERVABLE'; |
|
$datemsg = $reservable_now->{$reservable_now_order->[-1]}{'endreserve'}; |
|
} else { |
|
my ($uniqstart,$uniqend,$useslot); |
|
if (ref($consumed_uniq) eq 'ARRAY') { |
|
($uniqstart,$uniqend)=@{$consumed_uniq}; |
|
} |
|
foreach my $slot (reverse(@{$reservable_now_order})) { |
|
if ($reservable_now->{$slot}{'uniqueperiod'} =~ /^(\d+)\,(\d+)$/) { |
|
my ($new_uniq_start,$new_uniq_end) = ($1,$2); |
|
next if (! |
|
($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) || |
|
($uniqstart > $new_uniq_end && $uniqend > $new_uniq_end )); |
|
} |
|
$useslot = $slot; |
|
last; |
|
} |
|
if ($useslot) { |
|
$slotstatus = 'RESERVABLE'; |
|
$datemsg = $reservable_now->{$useslot}{'endreserve'}; |
|
} |
|
} |
|
} |
|
} |
|
unless ($slotstatus eq 'RESERVABLE') { |
|
if ((ref($reservable_future_order) eq 'ARRAY') && (ref($reservable_future) eq 'HASH')) { |
|
if (@{$reservable_future_order} > 0) { |
|
if ((!$checkedin) || (ref($consumed_uniq) ne 'ARRAY')) { |
|
$slotstatus = 'RESERVABLE_LATER'; |
|
$datemsg = $reservable_future->{$reservable_future_order->[0]}{'startreserve'}; |
|
} else { |
|
my ($uniqstart,$uniqend,$useslot); |
|
if (ref($consumed_uniq) eq 'ARRAY') { |
|
($uniqstart,$uniqend)=@{$consumed_uniq}; |
|
} |
|
foreach my $slot (@{$reservable_future_order}) { |
|
if ($reservable_future->{$slot}{'uniqueperiod'} =~ /^(\d+),(\d+)$/) { |
|
my ($new_uniq_start,$new_uniq_end) = ($1,$2); |
|
next if (! |
|
($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) || |
|
($uniqstart > $new_uniq_end && $uniqend > $new_uniq_end )); |
|
} |
|
$useslot = $slot; |
|
last; |
|
} |
|
if ($useslot) { |
|
$slotstatus = 'RESERVABLE_LATER'; |
|
$datemsg = $reservable_future->{$useslot}{'startreserve'}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
} |
} |
} |
return ($slotstatus,$datemsg); |
return ($slotstatus,$datemsg); |
Line 501 sub check_slot_access {
|
Line 440 sub check_slot_access {
|
} |
} |
|
|
if (($is_correct) && ($blockip ne 'answer')) { |
if (($is_correct) && ($blockip ne 'answer')) { |
if ($type eq 'problem') { |
if (($type eq 'problem') || ($type eq 'tool')) { |
return ($status); |
return ($status); |
} |
} |
return ('SHOW_ANSWER'); |
return ('SHOW_ANSWER'); |
Line 515 sub check_slot_access {
|
Line 454 sub check_slot_access {
|
return ($slotstatus,$datemsg,$slot_name,$returned_slot,$ipused); |
return ($slotstatus,$datemsg,$slot_name,$returned_slot,$ipused); |
} |
} |
|
|
|
sub check_reservable_slot { |
|
my ($slotstatus,$symb,$now,$checkedin,$consumed_uniq) = @_; |
|
my $datemsg; |
|
if ($slotstatus eq 'NOT_IN_A_SLOT') { |
|
if ($env{'request.course.id'}) { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
unless ($symb) { |
|
($symb)=&Apache::lonnet::whichuser(); |
|
} |
|
$slotstatus = 'NOTRESERVABLE'; |
|
my ($reservable_now_order,$reservable_now,$reservable_future_order, |
|
$reservable_future) = |
|
&Apache::loncommon::get_future_slots($cnum,$cdom,$now,$symb); |
|
if ((ref($reservable_now_order) eq 'ARRAY') && (ref($reservable_now) eq 'HASH')) { |
|
if (@{$reservable_now_order} > 0) { |
|
if ((!$checkedin) || (ref($consumed_uniq) ne 'ARRAY')) { |
|
$slotstatus = 'RESERVABLE'; |
|
$datemsg = $reservable_now->{$reservable_now_order->[-1]}{'endreserve'}; |
|
} else { |
|
my ($uniqstart,$uniqend,$useslot); |
|
if (ref($consumed_uniq) eq 'ARRAY') { |
|
($uniqstart,$uniqend)=@{$consumed_uniq}; |
|
} |
|
foreach my $slot (reverse(@{$reservable_now_order})) { |
|
if ($reservable_now->{$slot}{'uniqueperiod'} =~ /^(\d+)\,(\d+)$/) { |
|
my ($new_uniq_start,$new_uniq_end) = ($1,$2); |
|
next if (! |
|
($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) || |
|
($uniqstart > $new_uniq_end && $uniqend > $new_uniq_end )); |
|
} |
|
$useslot = $slot; |
|
last; |
|
} |
|
if ($useslot) { |
|
$slotstatus = 'RESERVABLE'; |
|
$datemsg = $reservable_now->{$useslot}{'endreserve'}; |
|
} |
|
} |
|
} |
|
} |
|
unless ($slotstatus eq 'RESERVABLE') { |
|
if ((ref($reservable_future_order) eq 'ARRAY') && (ref($reservable_future) eq 'HASH')) { |
|
if (@{$reservable_future_order} > 0) { |
|
if ((!$checkedin) || (ref($consumed_uniq) ne 'ARRAY')) { |
|
$slotstatus = 'RESERVABLE_LATER'; |
|
$datemsg = $reservable_future->{$reservable_future_order->[0]}{'startreserve'}; |
|
} else { |
|
my ($uniqstart,$uniqend,$useslot); |
|
if (ref($consumed_uniq) eq 'ARRAY') { |
|
($uniqstart,$uniqend)=@{$consumed_uniq}; |
|
} |
|
foreach my $slot (@{$reservable_future_order}) { |
|
if ($reservable_future->{$slot}{'uniqueperiod'} =~ /^(\d+),(\d+)$/) { |
|
my ($new_uniq_start,$new_uniq_end) = ($1,$2); |
|
next if (! |
|
($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) || |
|
($uniqstart > $new_uniq_end && $uniqend > $new_uniq_end )); |
|
} |
|
$useslot = $slot; |
|
last; |
|
} |
|
if ($useslot) { |
|
$slotstatus = 'RESERVABLE_LATER'; |
|
$datemsg = $reservable_future->{$useslot}{'startreserve'}; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return ($slotstatus,$datemsg); |
|
} |
|
|
# JB, 9/24/2002: Any changes in this function may require a change |
# JB, 9/24/2002: Any changes in this function may require a change |
# in lonnavmaps::resource::getDateStatus. |
# in lonnavmaps::resource::getDateStatus. |
sub check_access { |
sub check_access { |
Line 1661 sub handler {
|
Line 1675 sub handler {
|
} |
} |
# just render the page normally outside of construction space |
# just render the page normally outside of construction space |
&Apache::lonxml::debug("not construct"); |
&Apache::lonxml::debug("not construct"); |
|
undef(@Apache::lonhomework::ltipassback); |
&renderpage($request,$file,undef,undef,$donemsg); |
&renderpage($request,$file,undef,undef,$donemsg); |
|
if (@Apache::lonhomework::ltipassback) { |
|
unless ($registered_cleanup) { |
|
my $handlers = $request->get_handlers('PerlCleanupHandler'); |
|
$request->set_handlers('PerlCleanupHandler' => |
|
[\&do_ltipassback,@{$handlers}]); |
|
} |
|
} |
} |
} |
#my $td=&tv_interval($t0); |
#my $td=&tv_interval($t0); |
#&Apache::lonxml::debug("Spent $td seconds processing"); |
#&Apache::lonxml::debug("Spent $td seconds processing"); |
Line 1807 sub default_xml_tag {
|
Line 1829 sub default_xml_tag {
|
|
|
sub helpmenu_datastructure { |
sub helpmenu_datastructure { |
|
|
my $width = 500; |
# filename, title, width, height |
my $height = 600; |
|
|
|
my $helpers = [ |
my $helpers = [ |
['Problem_LON-CAPA_Functions', &mt('Script Functions')], |
['Problem_LON-CAPA_Functions.hlp', &mt('Script Functions'), 800, 600], |
['Greek_Symbols', &mt('Greek Symbols')], |
['Greek_Symbols.hlp', &mt('Greek Symbols'), 500, 600], |
['Other_Symbols', &mt('Other Symbols')], |
['Other_Symbols.hlp', &mt('Other Symbols'), 500, 600], |
['Authoring_Output_Tags', &mt('Output Tags')], |
['Authoring_Output_Tags.hlp', &mt('Output Tags'), 800, 600], |
['Authoring_Multilingual_Problems', |
['Authoring_Multilingual_Problems.hlp', |
&mt('How to create problems in different languages')] |
&mt('How to create problems in different languages'), 800, 600], |
|
['loncapa.html', &mt('Language reference'), 800, 600], |
]; |
]; |
|
|
my $help_structure = []; |
my $help_structure = []; |
Line 1824 sub helpmenu_datastructure {
|
Line 1845 sub helpmenu_datastructure {
|
foreach my $count (0..(scalar(@{$helpers})-1)) { |
foreach my $count (0..(scalar(@{$helpers})-1)) { |
my $filename = $helpers->[$count]->[0]; |
my $filename = $helpers->[$count]->[0]; |
my $title = $helpers->[$count]->[1]; |
my $title = $helpers->[$count]->[1]; |
my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');"); |
my $width = $helpers->[$count]->[2]; |
|
my $height = $helpers->[$count]->[3]; |
|
if ($width eq '') { |
|
$width = 500; |
|
} |
|
if ($height eq '') { |
|
$height = 600; |
|
} |
|
my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename',$width,$height,'yes');"); |
push @{$help_structure}, [$href, $title, undef]; |
push @{$help_structure}, [$href, $title, undef]; |
} |
} |
|
|
Line 1842 sub convert_for_js {
|
Line 1871 sub convert_for_js {
|
return $return; |
return $return; |
} |
} |
|
|
|
sub do_ltipassback { |
|
if (@Apache::lonhomework::ltipassback) { |
|
foreach my $item (@Apache::lonhomework::ltipassback) { |
|
if (ref($item) eq 'HASH') { |
|
if ((ref($item->{'lti'}) eq 'HASH') && ($item->{'cid'} =~ /^($match_domain)_($match_courseid)$/)) { |
|
my ($cdom,$cnum) = ($1,$2); |
|
my $ckey = $item->{'lti'}->{'key'}; |
|
my $secret = $item->{'lti'}->{'secret'}; |
|
my $id = $item->{'pbid'}; |
|
my $url = $item->{'pburl'}; |
|
my $scope = $item->{'scope'}; |
|
my $map = $item->{'ltimap'}; |
|
my $symb = $item->{'ltisymb'}; |
|
my $uname = $item->{'uname'}; |
|
my $udom = $item->{'udom'}; |
|
my $scoretype = $item->{'format'}; |
|
my ($total,$possible); |
|
if ($scope eq 'resource') { |
|
$total = $item->{'total'}; |
|
$possible = $item->{'possible'}; |
|
} elsif ($scope eq 'map') { |
|
($total,$possible) = &get_lti_score($uname,$udom,$map); |
|
} elsif ($scope eq 'course') { |
|
($total,$possible) = &get_lti_score($uname,$udom); |
|
} |
|
if (($ckey ne '') && ($secret ne '') && ($id ne '') && ($url ne '') && ($possible)) { |
|
&LONCAPA::ltiutils::send_grade($id,$url,$ckey,$secret,$scoretype,$total,$possible); |
|
} |
|
} |
|
} |
|
} |
|
undef(@Apache::lonhomework::ltipassback); |
|
} |
|
} |
|
|
|
sub get_lti_score { |
|
my ($uname,$udom,$mapurl) = @_; |
|
my $navmap = Apache::lonnavmaps::navmap->new($uname,$udom); |
|
if (ref($navmap)) { |
|
my $iterator; |
|
if ($mapurl ne '') { |
|
my $map = $navmap->getResourceByUrl($mapurl); |
|
my $firstres = $map->map_start(); |
|
my $finishres = $map->map_finish(); |
|
$iterator = $navmap->getIterator($firstres,$finishres,undef,1); |
|
} else { |
|
$iterator = $navmap->getIterator(undef,undef,undef,1); |
|
} |
|
if (ref($iterator)) { |
|
my $depth = 1; |
|
my $total = 0; |
|
my $possible = 0; |
|
$iterator->next(); # ignore first BEGIN_MAP |
|
my $curRes = $iterator->next(); |
|
while ( $depth > 0 ) { |
|
if ($curRes == $iterator->BEGIN_MAP()) {$depth++;} |
|
if ($curRes == $iterator->END_MAP()) { $depth--; } |
|
if (ref($curRes) && $curRes->is_gradable() && !$curRes->randomout) { |
|
my $parts = $curRes->parts(); |
|
foreach my $part (@{$parts}) { |
|
next if ($curRes->solved($part) eq 'excused'); |
|
$total += $curRes->weight($part) * $curRes->awarded($part); |
|
$possible += $curRes->weight($part); |
|
} |
|
} |
|
$curRes = $iterator->next(); |
|
} |
|
if ($total > $possible) { |
|
$total = $possible; |
|
} |
|
return ($total,$possible); |
|
} |
|
} |
|
return; |
|
} |
|
|
1; |
1; |
__END__ |
__END__ |