version 1.509.2.14.2.7, 2023/01/20 22:51:11
|
version 1.509.2.14.2.11, 2025/05/28 04:25:24
|
Line 534 my %colormap =
|
Line 534 my %colormap =
|
$resObj->EXCUSED => '#3333FF', |
$resObj->EXCUSED => '#3333FF', |
$resObj->PAST_DUE_ANSWER_LATER => '', |
$resObj->PAST_DUE_ANSWER_LATER => '', |
$resObj->PAST_DUE_NO_ANSWER => '', |
$resObj->PAST_DUE_NO_ANSWER => '', |
|
$resObj->PAST_DUE_ATMPT_ANS => '', |
|
$resObj->PAST_DUE_ATMPT_NOANS => '', |
|
$resObj->PAST_DUE_NO_ATMT_ANS => '', |
|
$resObj->PAST_DUE_NO_ATMT_NOANS => '', |
$resObj->ANSWER_OPEN => '#006600', |
$resObj->ANSWER_OPEN => '#006600', |
$resObj->OPEN_LATER => '', |
$resObj->OPEN_LATER => '', |
$resObj->TRIES_LEFT => '', |
$resObj->TRIES_LEFT => '', |
Line 679 sub getDescription {
|
Line 683 sub getDescription {
|
return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part).$slotinfo; |
return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part).$slotinfo; |
} |
} |
} |
} |
if ($status == $res->PAST_DUE_ANSWER_LATER) { |
if (($status == $res->PAST_DUE_ANSWER_LATER) || ($status == $res->PAST_DUE_ATMPT_ANS) || ($status == $res->PAST_DUE_NO_ATMT_ANS)) { |
return &mt("Answer open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part)); |
return &mt("Answer open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part)); |
} |
} |
if ($status == $res->PAST_DUE_NO_ANSWER) { |
if (($status == $res->PAST_DUE_NO_ANSWER) || ($status == $res->PAST_DUE_ATMPT_NOANS) || ($status == $res->PAST_DUE_NO_ATMT_NOANS)) { |
if ($res->is_practice()) { |
if ($res->is_practice()) { |
return &mt("Closed [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part)); |
return &mt("Closed [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part)); |
} else { |
} else { |
Line 691 sub getDescription {
|
Line 695 sub getDescription {
|
} |
} |
if (($status == $res->ANSWER_OPEN || $status == $res->PARTIALLY_CORRECT) |
if (($status == $res->ANSWER_OPEN || $status == $res->PARTIALLY_CORRECT) |
&& $res->handgrade($part) ne 'yes') { |
&& $res->handgrade($part) ne 'yes') { |
return &Apache::lonhtmlcommon::direct_parm_link(&mt("Answer available"),$res->symb(),'answerdate,duedate',$part); |
my $msg = &mt('Answer available'); |
|
my $parmlist = 'answerdate,duedate'; |
|
if (($res->is_tool) && ($res->is_gradable())) { |
|
if (($status == $res->PARTIALLY_CORRECT) && ($res->parmval('retrypartial',$part))) { |
|
$msg = &mt('Grade received'); |
|
$parmlist = 'retrypartial'; |
|
} else { |
|
$msg = &mt('Grade available'); |
|
} |
|
} |
|
return &Apache::lonhtmlcommon::direct_parm_link($msg,$res->symb(),$parmlist,$part); |
} |
} |
if ($status == $res->EXCUSED) { |
if ($status == $res->EXCUSED) { |
return &mt("Excused by instructor"); |
return &mt("Excused by instructor"); |
Line 1195 sub render_quick_status {
|
Line 1209 sub render_quick_status {
|
my $linkclose = "</a>"; |
my $linkclose = "</a>"; |
|
|
$result .= '<td class="LC_middle">'; |
$result .= '<td class="LC_middle">'; |
if ($resource->is_problem() && |
if ($resource->is_gradable() && |
!$firstDisplayed) { |
!$firstDisplayed) { |
my $icon = $statusIconMap{$resource->simpleStatus($part)}; |
my $icon = $statusIconMap{$resource->simpleStatus($part)}; |
my $alt = $iconAltTags{$icon}; |
my $alt = $iconAltTags{$icon}; |
Line 1220 sub render_long_status {
|
Line 1234 sub render_long_status {
|
|
|
my $color; |
my $color; |
my $info = ''; |
my $info = ''; |
if ($resource->is_problem() || $resource->is_practice()) { |
if ($resource->is_gradable() || $resource->is_practice()) { |
$color = $colormap{$resource->status}; |
$color = $colormap{$resource->status}; |
|
|
if (dueInLessThan24Hours($resource, $part)) { |
if (dueInLessThan24Hours($resource, $part)) { |
Line 1235 sub render_long_status {
|
Line 1249 sub render_long_status {
|
} |
} |
} |
} |
|
|
if ($resource->kind() eq "res" && |
if (($resource->kind() eq "res") && |
$resource->is_raw_problem() && |
($resource->is_raw_problem() || $resource->is_gradable()) && |
!$firstDisplayed) { |
!$firstDisplayed) { |
if ($color) {$result .= '<span style="color:'.$color.'"'.$info.'><b>'; } |
if ($color) {$result .= '<span style="color:'.$color.'"'.$info.'><b>'; } |
$result .= getDescription($resource, $part); |
$result .= getDescription($resource, $part); |
Line 1283 my @statuses = ($resObj->CORRECT, $resOb
|
Line 1297 my @statuses = ($resObj->CORRECT, $resOb
|
|
|
sub render_parts_summary_status { |
sub render_parts_summary_status { |
my ($resource, $part, $params) = @_; |
my ($resource, $part, $params) = @_; |
if (!$resource->is_problem() && !$resource->contains_problem) { return '<td></td>'; } |
if (!$resource->is_gradable() && !$resource->contains_problem) { return '<td></td>'; } |
if ($params->{showParts}) { |
if ($params->{showParts}) { |
return '<td></td>'; |
return '<td></td>'; |
} |
} |
Line 1352 sub cmp_title {
|
Line 1366 sub cmp_title {
|
sub render { |
sub render { |
my $args = shift; |
my $args = shift; |
&Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); |
&Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); |
my $result = ''; |
|
# Configure the renderer. |
# Configure the renderer. |
my $cols = $args->{'cols'}; |
my $cols = $args->{'cols'}; |
if (!defined($cols)) { |
if (!defined($cols)) { |
# no columns, no nav maps. |
# no columns, no nav maps. |
return ''; |
return ''; |
} |
} |
|
my $legend = ''; |
|
my $tools = ''; |
|
my $result = ''; |
|
my $tools_printed = 0; |
|
my $tablestarted = 0; |
my $navmap; |
my $navmap; |
if (defined($args->{'navmap'})) { |
if (defined($args->{'navmap'})) { |
$navmap = $args->{'navmap'}; |
$navmap = $args->{'navmap'}; |
Line 1570 sub render {
|
Line 1588 sub render {
|
|
|
# Print key? |
# Print key? |
if ($printKey) { |
if ($printKey) { |
$result .= '<table border="0" cellpadding="2" cellspacing="0">'; |
$legend = '<table border="0" cellpadding="2" cellspacing="0">'; |
$result.='<tr><td align="right" valign="bottom">Key: </td>'; |
$legend .= '<tr><td align="right" valign="bottom">Key: </td>'; |
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
if ($navmap->{LAST_CHECK}) { |
if ($navmap->{LAST_CHECK}) { |
$result .= |
$legend .= |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('New discussion since').' '. |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('New discussion since').' '. |
strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). |
strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). |
'</td><td align="center" valign="bottom"> '. |
'</td><td align="center" valign="bottom"> '. |
'<img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)').'<p>'. |
'<img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)').'<p>'. |
'</td>'; |
'</td>'; |
} else { |
} else { |
$result .= '<td align="center" valign="bottom"> '. |
$legend .= '<td align="center" valign="bottom"> '. |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('Discussions').'</td><td align="center" valign="bottom">'. |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('Discussions').'</td><td align="center" valign="bottom">'. |
' <img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)'). |
' <img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)'). |
'</td>'; |
'</td>'; |
} |
} |
|
|
$result .= '</tr></table>'; |
$legend .= '</tr></table>'; |
} |
} |
|
|
if ($printCloseAll && !$args->{'resource_no_folder_link'}) { |
if ($printCloseAll && !$args->{'resource_no_folder_link'}) { |
Line 1607 sub render {
|
Line 1625 sub render {
|
"location.href='$link'",$text); |
"location.href='$link'",$text); |
} |
} |
} else { |
} else { |
$result.= '<a href="'.$link.'">'.&mt($text).'</a>'; |
$tools = '<a href="'.$link.'">'.&mt($text).'</a>'; |
} |
} |
$result .= "\n"; |
$tools .= "\n"; |
} |
} |
|
|
# Check for any unread discussions in all resources. |
# Check for any unread discussions in all resources. |
Line 1619 sub render {
|
Line 1637 sub render {
|
'Mark all posts read'); |
'Mark all posts read'); |
my $time=time; |
my $time=time; |
my $querystr = &HTML::Entities::encode($ENV{'QUERY_STRING'},'<>&"'); |
my $querystr = &HTML::Entities::encode($ENV{'QUERY_STRING'},'<>&"'); |
$result .= (<<END); |
$tools .= (<<END); |
<form name="clearbubbles" method="post" action="/adm/feedback"> |
<form name="clearbubbles" method="post" action="/adm/feedback"> |
<input type="hidden" name="navurl" value="$querystr" /> |
<input type="hidden" name="navurl" value="$querystr" /> |
<input type="hidden" name="navtime" value="$time" /> |
<input type="hidden" name="navtime" value="$time" /> |
Line 1636 END
|
Line 1654 END
|
} |
} |
if ($totdisc > 0) { |
if ($totdisc > 0) { |
$haveDisc =~ s/:$//; |
$haveDisc =~ s/:$//; |
$result .= (<<END); |
$tools .= (<<END); |
<input type="hidden" name="navmaps" value="$haveDisc" /> |
<input type="hidden" name="navmaps" value="$haveDisc" /> |
</form> |
</form> |
END |
END |
} |
} |
} |
} |
$result.='</form>'; |
$tools .= '</form>'; |
} |
} |
if (($args->{'caller'} eq 'navmapsdisplay') && ($env{'request.course.id'})) { |
if (($args->{'caller'} eq 'navmapsdisplay') && ($env{'request.course.id'})) { |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
Line 1664 END
|
Line 1682 END
|
} |
} |
|
|
if ($args->{'caller'} eq 'navmapsdisplay') { |
if ($args->{'caller'} eq 'navmapsdisplay') { |
$result .= &show_linkitems_toolbar($args,$condition); |
$tools .= &show_linkitems_toolbar($args,$condition); |
} elsif ($args->{'sort_html'}) { |
} elsif ($args->{'sort_html'}) { |
$result.=$args->{'sort_html'}; |
$tools .= $args->{'sort_html'}; |
} |
} |
|
|
#$result .= "<br />\n"; |
#$tools .= "<br />\n"; |
if ($r) { |
|
$r->print($result); |
|
$r->rflush(); |
|
$result = ""; |
|
} |
|
# End parameter setting |
# End parameter setting |
|
|
$result .= "<br />\n"; |
|
|
|
# Data |
# Data |
$result.=&Apache::loncommon::start_data_table("LC_tableOfContent"); |
|
|
|
my $res = "Apache::lonnavmaps::resource"; |
my $res = "Apache::lonnavmaps::resource"; |
my %condenseStatuses = |
my %condenseStatuses = |
Line 1914 END
|
Line 1924 END
|
} |
} |
|
|
$args->{'counter'}++; |
$args->{'counter'}++; |
|
unless ($tablestarted) { |
|
$result .= "<br />\n".&Apache::loncommon::start_data_table("LC_tableOfContent"); |
|
$tablestarted = 1; |
|
} |
|
|
# Does it have multiple parts? |
# Does it have multiple parts? |
$args->{'multipart'} = 0; |
$args->{'multipart'} = 0; |
Line 2064 END
|
Line 2078 END
|
} |
} |
|
|
if ($r && $rownum % 20 == 0) { |
if ($r && $rownum % 20 == 0) { |
|
unless ($tools_printed) { |
|
$r->print($legend.$tools); |
|
$legend = ""; |
|
$tools = ""; |
|
$tools_printed = 1; |
|
} |
$r->print($result); |
$r->print($result); |
$result = ""; |
$result = ""; |
$r->rflush(); |
$r->rflush(); |
Line 2079 END
|
Line 2099 END
|
} |
} |
} |
} |
|
|
$result.=&Apache::loncommon::end_data_table(); |
if ($tablestarted) { |
|
$result.=&Apache::loncommon::end_data_table(); |
|
} |
|
|
# Print out the part that jumps to #curloc if it exists |
# Print out the part that jumps to #curloc if it exists |
# delay needed because the browser is processing the jump before |
# delay needed because the browser is processing the jump before |
# it finishes rendering, so it goes to the wrong place! |
# it finishes rendering, so it goes to the wrong place! |
Line 2097 if (location.href.indexOf('#curloc')==-1
|
Line 2119 if (location.href.indexOf('#curloc')==-1
|
} |
} |
|
|
if ($r) { |
if ($r) { |
|
unless ($tools_printed) { |
|
if (($args->{'counter'}) || ($userCanSeeHidden) || |
|
(($args->{'caller'} eq 'navmapsdisplay') && |
|
($env{'form.showOnlyHomework'} || |
|
$ENV{QUERY_STRING} =~ /^jumpToFirstHomework/))) { |
|
$r->print($legend.$tools); |
|
} |
|
$legend = ""; |
|
$tools = ""; |
|
$tools_printed = 1; |
|
} |
$r->print($result); |
$r->print($result); |
$result = ""; |
$result = ""; |
$r->rflush(); |
$r->rflush(); |
} |
} |
|
|
return $result; |
return $legend.$tools.$result; |
} |
} |
|
|
sub add_linkitem { |
sub add_linkitem { |
Line 2260 sub new {
|
Line 2293 sub new {
|
|
|
$self->{USERNAME} = shift || $env{'user.name'}; |
$self->{USERNAME} = shift || $env{'user.name'}; |
$self->{DOMAIN} = shift || $env{'user.domain'}; |
$self->{DOMAIN} = shift || $env{'user.domain'}; |
|
$self->{SECTION} = shift; |
$self->{CODE} = shift; |
$self->{CODE} = shift; |
$self->{NOHIDE} = shift; |
$self->{NOHIDE} = shift; |
|
|
|
|
|
if (($self->{SECTION} eq '') && ($env{'request.course.sec'} ne '')) { |
|
if (($self->{USERNAME} eq $env{'user.name'}) && |
|
($self->{USERNAME} eq $env{'user.domain'})) { |
|
$self->{SECTION} = $env{'request.course.sec'}; |
|
} |
|
} |
|
|
# Resource cache stores navmap resources as we reference them. We generate |
# Resource cache stores navmap resources as we reference them. We generate |
# them on-demand so we don't pay for creating resources unless we use them. |
# them on-demand so we don't pay for creating resources unless we use them. |
Line 2305 sub new {
|
Line 2345 sub new {
|
$self->{PARM_HASH} = \%parmhash; |
$self->{PARM_HASH} = \%parmhash; |
$self->{PARM_CACHE} = {}; |
$self->{PARM_CACHE} = {}; |
} else { |
} else { |
$self->change_user($self->{USERNAME}, $self->{DOMAIN}, $self->{CODE}, $self->{NOHIDE}); |
$self->change_user($self->{USERNAME}, $self->{DOMAIN}, $self->{SECTION}, $self->{CODE}, $self->{NOHIDE}); |
} |
} |
|
|
return $self; |
return $self; |
Line 2316 sub new {
|
Line 2356 sub new {
|
# username/domain associated with a navmap (e.g. to navigate for someone |
# username/domain associated with a navmap (e.g. to navigate for someone |
# else besides the current user...if sufficiently privileged. |
# else besides the current user...if sufficiently privileged. |
# Parameters: |
# Parameters: |
# user - New user. |
# user - New user. |
# domain- Domain the user belongs to. |
# domain - Domain to which the user belongs. |
# code - Anonymous CODE in use. |
# section - Section to which the user belongs. |
|
# code - Anonymous CODE in use. |
# Implicit inputs: |
# Implicit inputs: |
# |
# |
sub change_user { |
sub change_user { |
my $self = shift; |
my $self = shift; |
$self->{USERNAME} = shift; |
$self->{USERNAME} = shift; |
$self->{DOMAIN} = shift; |
$self->{DOMAIN} = shift; |
|
$self->{SECTION} = shift; |
$self->{CODE} = shift; |
$self->{CODE} = shift; |
$self->{NOHIDE} = shift; |
$self->{NOHIDE} = shift; |
|
|
Line 2830 sub parmval_real {
|
Line 2872 sub parmval_real {
|
$self->generate_course_user_opt(); |
$self->generate_course_user_opt(); |
|
|
my $cid=$env{'request.course.id'}; |
my $cid=$env{'request.course.id'}; |
my $csec=$env{'request.course.sec'}; |
my $csec=$self->{SECTION}; |
my $cgroup=''; |
my $cgroup=''; |
my @cgrps=split(/:/,$env{'request.course.groups'}); |
my @cgrps=split(/:/,$env{'request.course.groups'}); |
if (@cgrps > 0) { |
if (@cgrps > 0) { |
Line 2845 sub parmval_real {
|
Line 2887 sub parmval_real {
|
|
|
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
$mapname = &Apache::lonnet::deversion($mapname); |
$mapname = &Apache::lonnet::deversion($mapname); |
|
my $toolsymb = ''; |
|
if ($fn =~ /ext\.tool$/) { |
|
$toolsymb = $symb; |
|
} |
# ----------------------------------------------------- Cascading lookup scheme |
# ----------------------------------------------------- Cascading lookup scheme |
my $rwhat=$what; |
my $rwhat=$what; |
$what=~s/^parameter\_//; |
$what=~s/^parameter\_//; |
Line 2908 sub parmval_real {
|
Line 2954 sub parmval_real {
|
|
|
my $meta_rwhat=$rwhat; |
my $meta_rwhat=$rwhat; |
$meta_rwhat=~s/\./_/g; |
$meta_rwhat=~s/\./_/g; |
my $default=&Apache::lonnet::metadata($fn,$meta_rwhat); |
my $default=&Apache::lonnet::metadata($fn,$meta_rwhat,$toolsymb); |
if (defined($default)) { return [$default,'resource']} |
if (defined($default)) { return [$default,'resource']} |
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat); |
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat,$toolsymb); |
if (defined($default)) { return [$default,'resource']} |
if (defined($default)) { return [$default,'resource']} |
# --------------------------------------------------- fifth, check more course |
# --------------------------------------------------- fifth, check more course |
if (defined($courseopt)) { |
if (defined($courseopt)) { |
Line 2933 sub parmval_real {
|
Line 2979 sub parmval_real {
|
if (defined($partgeneral[0])) { return \@partgeneral; } |
if (defined($partgeneral[0])) { return \@partgeneral; } |
} |
} |
if ($recurse) { return []; } |
if ($recurse) { return []; } |
my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat); |
my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat,$toolsymb); |
if (defined($pack_def)) { return [$pack_def,'resource']; } |
if (defined($pack_def)) { return [$pack_def,'resource']; } |
return ['']; |
return ['']; |
} |
} |
|
|
sub recurseup_maps { |
sub recurseup_maps { |
my ($self,$mapname) = @_; |
my ($self,$mapname,$getsymb) = @_; |
my @recurseup; |
my @recurseup; |
if ($mapname) { |
if ($mapname) { |
my $res = $self->getResourceByUrl($mapname); |
my $res = $self->getResourceByUrl($mapname); |
Line 2947 sub recurseup_maps {
|
Line 2993 sub recurseup_maps {
|
my @pcs = split(/,/,$res->map_hierarchy()); |
my @pcs = split(/,/,$res->map_hierarchy()); |
shift(@pcs); |
shift(@pcs); |
if (@pcs) { |
if (@pcs) { |
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); |
if ($getsymb) { |
|
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->symb()); } reverse(@pcs); |
|
} else { |
|
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); |
|
} |
} |
} |
} |
} |
} |
} |
Line 3075 sub get_mapparam {
|
Line 3125 sub get_mapparam {
|
# Get the course id and section if there is one. |
# Get the course id and section if there is one. |
|
|
my $cid=$env{'request.course.id'}; |
my $cid=$env{'request.course.id'}; |
my $csec=$env{'request.course.sec'}; |
my $csec=$self->{SECTION}; |
my $cgroup=''; |
my $cgroup=''; |
my @cgrps=split(/:/,$env{'request.course.groups'}); |
my @cgrps=split(/:/,$env{'request.course.groups'}); |
if (@cgrps > 0) { |
if (@cgrps > 0) { |
Line 3244 sub getcourseparam {
|
Line 3294 sub getcourseparam {
|
|
|
my $uname = $self->{USERNAME}; |
my $uname = $self->{USERNAME}; |
my $udom = $self->{DOMAIN}; |
my $udom = $self->{DOMAIN}; |
|
my $csec = $self->{SECTION}; |
|
|
# Course, section, group ids come from the env: |
# Course and group ids come from the env: |
|
|
my $cid = $env{'request.course.id'}; |
my $cid = $env{'request.course.id'}; |
my $csec = $env{'request.course.sec'}; |
|
my $cgroup = ''; # Assume no group |
my $cgroup = ''; # Assume no group |
|
|
my @cgroups = split(/:/, $env{'request.course.groups'}); |
my @cgroups = split(/:/, $env{'request.course.groups'}); |
Line 3485 sub usedVersion {
|
Line 3535 sub usedVersion {
|
return $self->navhash("version_$linkurl"); |
return $self->navhash("version_$linkurl"); |
} |
} |
|
|
|
sub isFirstResource { |
|
my $self = shift; |
|
my $map = shift; |
|
my $symb = shift; |
|
return unless (ref($map)); |
|
my $isfirst; |
|
my $firstResource = $map->map_start(); |
|
if (ref($firstResource)) { |
|
if ((!$firstResource->is_map()) && ($firstResource->src() ne '')) { |
|
if ($firstResource->symb() eq $symb) { |
|
$isfirst = 1; |
|
} else { |
|
$isfirst = 0; |
|
} |
|
} else { |
|
my $it = $self->getIterator($firstResource,undef,undef,1); |
|
while ( my $res=$it->next()) { |
|
if ((ref($res)) && ($res->src() ne '') && (!$res->is_map())) { |
|
if ($res->symb() eq $symb) { |
|
$isfirst = 1; |
|
} else { |
|
$isfirst = 0; |
|
} |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
return $isfirst; |
|
} |
|
|
|
sub isLastResource { |
|
my $self = shift; |
|
my $map = shift; |
|
my $symb = shift; |
|
return unless (ref($map)); |
|
my $islast; |
|
my $lastResource = $map->map_finish(); |
|
if (ref($lastResource)) { |
|
if ((!$lastResource->is_map()) && ($lastResource->src() ne '')) { |
|
if ($lastResource->symb() eq $symb) { |
|
$islast = 1; |
|
} else { |
|
$islast = 0; |
|
} |
|
} else { |
|
my $currRes = $self->getBySymb($symb); |
|
if (ref($currRes)) { |
|
my $it = $self->getIterator($currRes,undef,undef,1); |
|
while ( my $res=$it->next()) { |
|
if ((ref($res)) && ($res->src() ne '') && (!$res->is_map())) { |
|
if ($res->symb() eq $symb) { |
|
$islast = 1; |
|
} else { |
|
$islast = 0; |
|
} |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return $islast; |
|
} |
|
|
1; |
1; |
|
|
package Apache::lonnavmaps::iterator; |
package Apache::lonnavmaps::iterator; |
Line 4542 sub is_problem {
|
Line 4657 sub is_problem {
|
} |
} |
return 0; |
return 0; |
} |
} |
|
sub is_tool { |
|
my $self=shift; |
|
my $src = $self->src(); |
|
return ($src =~ /ext\.tool$/); |
|
} |
|
sub is_gradable { |
|
my $self=shift; |
|
my $src = $self->src(); |
|
if (($src =~ /$LONCAPA::assess_re/) || |
|
(($self->is_tool()) && ($self->parmval('gradable',0) =~ /^yes$/i))) { |
|
return !($self->is_practice()); |
|
} |
|
} |
# |
# |
# The has below is the set of status that are considered 'incomplete' |
# The has below is the set of status that are considered 'incomplete' |
# |
# |
Line 5032 sub weight {
|
Line 5160 sub weight {
|
my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', |
my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', |
$self->{SYMB}, $self->{DOMAIN}, |
$self->{SYMB}, $self->{DOMAIN}, |
$self->{USERNAME}, |
$self->{USERNAME}, |
$env{'request.course.sec'}); |
$self->{SECTION}); |
return $weight; |
return $weight; |
} |
} |
sub part_display { |
sub part_display { |
Line 5241 sub parts {
|
Line 5369 sub parts {
|
my $self = shift; |
my $self = shift; |
|
|
if ($self->ext) { return []; } |
if ($self->ext) { return []; } |
|
if (($self->is_tool()) && |
|
($self->is_gradable())) { return ['0']; } |
|
|
$self->extractParts(); |
$self->extractParts(); |
return $self->{PARTS}; |
return $self->{PARTS}; |
Line 5331 sub extractParts {
|
Line 5461 sub extractParts {
|
my %parts; |
my %parts; |
|
|
# Retrieve part count, if this is a problem |
# Retrieve part count, if this is a problem |
if ($self->is_problem()) { |
if ($self->is_raw_problem()) { |
my $partorder = &Apache::lonnet::metadata($self->src(), 'partorder'); |
my $partorder = &Apache::lonnet::metadata($self->src(), 'partorder'); |
my $metadata = &Apache::lonnet::metadata($self->src(), 'packages'); |
my $metadata = &Apache::lonnet::metadata($self->src(), 'packages'); |
|
|
Line 5498 The problem will be opened later.
|
Line 5628 The problem will be opened later.
|
|
|
Open and not yet due. |
Open and not yet due. |
|
|
|
|
=item * B<PAST_DUE_ANSWER_LATER>: |
=item * B<PAST_DUE_ANSWER_LATER>: |
|
|
The due date has passed, but the answer date has not yet arrived. |
The due date has passed, but the answer date has not yet arrived. |
Line 5511 The due date has passed and there is no
|
Line 5640 The due date has passed and there is no
|
|
|
The answer date is here. |
The answer date is here. |
|
|
|
=item * B<NOTHING_SET>: |
|
|
|
No dates have been set for this problem at all. |
|
|
|
=item * B<PAST_DUE_ATMPT_ANS>: |
|
|
|
The due date has passed, feedback is suppressed, the problem was attempted, and the answer date has not yet arrived. |
|
|
|
=item * B<PAST_DUE_ATMPT_NOANS>: |
|
|
|
The due date has passed, feedback is suppressed, the problem was attempted, and there is no answer opening date set. |
|
|
|
=item * B<PAST_DUE_NO_ATMT_ANS>: |
|
|
|
The due date has passed, feedback is suppressed, the problem was not attempted, and the answer date has not yet arrived. |
|
|
|
=item * B<PAST_DUE_NO_ATMT_NOANS>: |
|
|
|
The due date has passed, feedback is suppressed, the problem was not attempted, and there is no answer opening date set. |
|
|
=item * B<NETWORK_FAILURE>: |
=item * B<NETWORK_FAILURE>: |
|
|
The information is unknown due to network failure. |
The information is unknown due to network failure. |
Line 5526 sub PAST_DUE_NO_ANSWER { return 2; }
|
Line 5675 sub PAST_DUE_NO_ANSWER { return 2; }
|
sub PAST_DUE_ANSWER_LATER { return 3; } |
sub PAST_DUE_ANSWER_LATER { return 3; } |
sub ANSWER_OPEN { return 4; } |
sub ANSWER_OPEN { return 4; } |
sub NOTHING_SET { return 5; } |
sub NOTHING_SET { return 5; } |
|
sub PAST_DUE_ATMPT_ANS { return 6; } |
|
sub PAST_DUE_ATMPT_NOANS { return 7; } |
|
sub PAST_DUE_NO_ATMT_ANS { return 8; } |
|
sub PAST_DUE_NO_ATMT_NOANS { return 9; } |
sub NETWORK_FAILURE { return 100; } |
sub NETWORK_FAILURE { return 100; } |
|
|
# getDateStatus gets the date status for a given problem part. |
# getDateStatus gets the date status for a given problem part. |
Line 5615 Attempted, and not yet graded.
|
Line 5768 Attempted, and not yet graded.
|
|
|
Attempted, and credit received for attempt (survey and anonymous survey only). |
Attempted, and credit received for attempt (survey and anonymous survey only). |
|
|
|
=item * B<INCORRECT_BY_PASSBACK>: |
|
|
|
Attempted, but wrong for LTI Tool Provider by passback of grade |
|
|
|
=item * B<CORRECT_BY_PASSBACK>: |
|
|
|
Correct for LTI Tool Provider by passback of grade |
|
|
=back |
=back |
|
|
=cut |
=cut |
Line 5627 sub CORRECT_BY_OVERRIDE { return 14; }
|
Line 5788 sub CORRECT_BY_OVERRIDE { return 14; }
|
sub EXCUSED { return 15; } |
sub EXCUSED { return 15; } |
sub ATTEMPTED { return 16; } |
sub ATTEMPTED { return 16; } |
sub CREDIT_ATTEMPTED { return 17; } |
sub CREDIT_ATTEMPTED { return 17; } |
|
sub INCORRECT_BY_PASSBACK { return 18; } |
|
sub CORRECT_BY_PASSBACK { return 19; } |
|
|
sub getCompletionStatus { |
sub getCompletionStatus { |
my $self = shift; |
my $self = shift; |
Line 5641 sub getCompletionStatus {
|
Line 5804 sub getCompletionStatus {
|
if ($status eq 'correct_by_override') { |
if ($status eq 'correct_by_override') { |
return $self->CORRECT_BY_OVERRIDE; |
return $self->CORRECT_BY_OVERRIDE; |
} |
} |
|
if ($status eq 'correct_by_passback') { |
|
return $self->CORRECT_BY_PASSBACK; |
|
} |
if ($status eq 'incorrect_attempted') {return $self->INCORRECT; } |
if ($status eq 'incorrect_attempted') {return $self->INCORRECT; } |
if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; } |
if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; } |
|
if ($status eq 'incorrect_by_passback') {return $self->INCORRECT_BY_PASSBACK; } |
if ($status eq 'excused') {return $self->EXCUSED; } |
if ($status eq 'excused') {return $self->EXCUSED; } |
if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } |
if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } |
if ($status eq 'credit_attempted') { |
if ($status eq 'credit_attempted') { |
Line 5715 set.
|
Line 5882 set.
|
The problem is past due, not considered correct, and an answer date in |
The problem is past due, not considered correct, and an answer date in |
the future is set. |
the future is set. |
|
|
|
=item * B<PAST_DUE_ATMPT_ANS>: |
|
|
|
The problem is past due, feedback is suppressed, the problem was |
|
attempted and an answer date in the future is set. |
|
|
|
=item * B<PAST_DUE_ATMPT_NOANS>: |
|
|
|
The problem is past due, feedback is suppressed, the problem was |
|
attempted and no answer date is set. |
|
|
|
=item * B<PAST_DUE_NO_ATMT_ANS>: |
|
|
|
The problem is past due, feedback is suppressed, the problem was |
|
not attempted and an answer date in the future is set. |
|
|
|
=item * B<PAST_DUE_NO_ATMT_NOANS>: |
|
|
|
The problem is past due, feedback is suppressed, the problem was |
|
not attempted and no answer date is set. |
|
|
=item * B<ANSWER_OPEN>: |
=item * B<ANSWER_OPEN>: |
|
|
The problem is past due, not correct, and the answer is now available. |
The problem is past due, not correct, and the answer is now available. |
Line 5796 sub status {
|
Line 5983 sub status {
|
|
|
# There are a few whole rows we can dispose of: |
# There are a few whole rows we can dispose of: |
if ($completionStatus == CORRECT || |
if ($completionStatus == CORRECT || |
$completionStatus == CORRECT_BY_OVERRIDE ) { |
$completionStatus == CORRECT_BY_OVERRIDE || |
if ( $suppressFeedback ) { return ANSWER_SUBMITTED } |
$completionStatus == CORRECT_BY_PASSBACK ) { |
|
if ( $suppressFeedback ) { |
|
if ($dateStatus == PAST_DUE_ANSWER_LATER || |
|
$dateStatus == PAST_DUE_NO_ANSWER ) { |
|
if ($dateStatus == PAST_DUE_ANSWER_LATER) { |
|
return PAST_DUE_ATMPT_ANS; |
|
} else { |
|
return PAST_DUE_ATMPT_NOANS; |
|
} |
|
} else { |
|
return ANSWER_SUBMITTED; |
|
} |
|
} |
my $awarded=$self->awarded($part); |
my $awarded=$self->awarded($part); |
if ($awarded < 1 && $awarded > 0) { |
if ($awarded < 1 && $awarded > 0) { |
return PARTIALLY_CORRECT; |
return PARTIALLY_CORRECT; |
Line 5809 sub status {
|
Line 6008 sub status {
|
|
|
# If it's WRONG... and not open |
# If it's WRONG... and not open |
if ( ($completionStatus == INCORRECT || |
if ( ($completionStatus == INCORRECT || |
$completionStatus == INCORRECT_BY_OVERRIDE) |
$completionStatus == INCORRECT_BY_OVERRIDE || |
|
$completionStatus == INCORRECT_BY_PASSBACK) |
&& (!$self->opendate($part) || $self->opendate($part) > time()) ) { |
&& (!$self->opendate($part) || $self->opendate($part) > time()) ) { |
return INCORRECT; |
return INCORRECT; |
} |
} |
Line 5836 sub status {
|
Line 6036 sub status {
|
|
|
if ($dateStatus == PAST_DUE_ANSWER_LATER || |
if ($dateStatus == PAST_DUE_ANSWER_LATER || |
$dateStatus == PAST_DUE_NO_ANSWER ) { |
$dateStatus == PAST_DUE_NO_ANSWER ) { |
return $suppressFeedback ? ANSWER_SUBMITTED : $dateStatus; |
if ($suppressFeedback) { |
|
if ($completionStatus == NOT_ATTEMPTED) { |
|
if ($dateStatus == PAST_DUE_ANSWER_LATER) { |
|
return PAST_DUE_NO_ATMT_ANS; |
|
} else { |
|
return PAST_DUE_NO_ATMT_NOANS; |
|
} |
|
} else { |
|
if ($dateStatus == PAST_DUE_ANSWER_LATER) { |
|
return PAST_DUE_ATMPT_ANS; |
|
} else { |
|
return PAST_DUE_ATMPT_NOANS; |
|
} |
|
} |
|
} else { |
|
return $dateStatus; |
|
} |
} |
} |
|
|
if ($dateStatus == ANSWER_OPEN) { |
if ($dateStatus == ANSWER_OPEN) { |
Line 5851 sub status {
|
Line 6067 sub status {
|
} |
} |
|
|
# If it's WRONG... |
# If it's WRONG... |
if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE) { |
if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE || |
|
$completionStatus == INCORRECT_BY_PASSBACK) { |
# and there are TRIES LEFT: |
# and there are TRIES LEFT: |
if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) { |
if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) { |
return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT; |
return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT; |
Line 6046 my %compositeToSimple =
|
Line 6263 my %compositeToSimple =
|
EXCUSED() => CORRECT, |
EXCUSED() => CORRECT, |
PAST_DUE_NO_ANSWER() => INCORRECT, |
PAST_DUE_NO_ANSWER() => INCORRECT, |
PAST_DUE_ANSWER_LATER() => INCORRECT, |
PAST_DUE_ANSWER_LATER() => INCORRECT, |
|
PAST_DUE_ATMPT_ANS() => ATTEMPTED, |
|
PAST_DUE_ATMPT_NOANS() => ATTEMPTED, |
|
PAST_DUE_NO_ATMT_ANS() => CLOSED, |
|
PAST_DUE_NO_ATMT_NOANS() => CLOSED, |
ANSWER_OPEN() => INCORRECT, |
ANSWER_OPEN() => INCORRECT, |
OPEN_LATER() => CLOSED, |
OPEN_LATER() => CLOSED, |
TRIES_LEFT() => OPEN, |
TRIES_LEFT() => OPEN, |