version 1.566, 2024/12/10 04:52:30
|
version 1.577, 2025/06/28 17:34:00
|
Line 48 described at http://www.lon-capa.org.
|
Line 48 described at http://www.lon-capa.org.
|
|
|
=head1 OVERVIEW |
=head1 OVERVIEW |
|
|
X<lonnavmaps, overview> When a user enters a course, LON-CAPA examines the |
X<lonnavmaps, overview> |
|
When a user enters a course, LON-CAPA examines the |
course structure and caches it in what is often referred to as the |
course structure and caches it in what is often referred to as the |
"big hash" X<big hash>. You can see it if you are logged into |
"big hash" X<big hash>. You can see it if you are logged into |
LON-CAPA, in a course, by going to /adm/test. The content of |
LON-CAPA, in a course, by going to /adm/test. The content of |
Line 424 Convenience function, so others can use
|
Line 425 Convenience function, so others can use
|
Convenience function, so others can use it: Is there only one try remaining for the |
Convenience function, so others can use it: Is there only one try remaining for the |
part, with more than one try to begin with, not due yet and still can be done? |
part, with more than one try to begin with, not due yet and still can be done? |
|
|
|
=item graceEndsUnder24Hours() |
|
|
|
Convenience function, so others can use it: Is the problem past-due with a grace period |
|
which ends in less than 24 hours, and still can be done? |
|
|
=item advancedUser() |
=item advancedUser() |
|
|
This puts a human-readable name on the env variable. |
This puts a human-readable name on the env variable. |
Line 636 sub getDescription {
|
Line 642 sub getDescription {
|
|
|
my $open = $res->opendate($part); |
my $open = $res->opendate($part); |
my $due = $res->duedate($part); |
my $due = $res->duedate($part); |
|
my $overdue = $res->overduedate($part); |
my $answer = $res->answerdate($part); |
my $answer = $res->answerdate($part); |
|
|
if ($status == $res->NETWORK_FAILURE) { |
if ($status == $res->NETWORK_FAILURE) { |
Line 689 sub getDescription {
|
Line 696 sub getDescription {
|
} |
} |
if ($status == $res->OPEN) { |
if ($status == $res->OPEN) { |
if ($due) { |
if ($due) { |
if ($res->is_practice()) { |
my $now = time; |
return &mt("Closes [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'duedate',$part)).$slotinfo; |
if (($now >= $due) && ($overdue) && ($now < $overdue)) { |
} else { |
if ($res->is_practice()) { |
return &mt("Due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part)).$slotinfo; |
return &mt("Closes [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($overdue,'start'),$res->symb(),'duedate',$part)).$slotinfo; |
} |
} else { |
|
return &mt("Grace period ends [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($overdue,'end'),$res->symb(),'grace',$part)).$slotinfo; |
|
} |
|
} else { |
|
if ($res->is_practice()) { |
|
return &mt("Closes [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'duedate',$part)).$slotinfo; |
|
} else { |
|
return &mt("Due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part)).$slotinfo; |
|
} |
|
} |
} else { |
} else { |
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; |
} |
} |
Line 748 sub getDescription {
|
Line 764 sub getDescription {
|
} |
} |
} |
} |
if ($due) { |
if ($due) { |
return &mt("Due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part)) . |
my $now = time; |
" $triesString"; |
if (($now >= $due) && ($overdue) && ($now < $overdue)) { |
|
return &mt("Grace period ends [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($overdue,'end'),$res->symb(),'grace',$part)). |
|
" $triesString"; |
|
} else { |
|
return &mt("Due [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'end'),$res->symb(),'duedate',$part)) . |
|
" $triesString"; |
|
} |
} else { |
} else { |
return &Apache::lonhtmlcommon::direct_parm_link(&mt("No due date"),$res->symb(),'duedate',$part)." $triesString"; |
return &Apache::lonhtmlcommon::direct_parm_link(&mt("No due date"),$res->symb(),'duedate',$part)." $triesString"; |
} |
} |
Line 783 sub lastTry {
|
Line 805 sub lastTry {
|
$res->duedate($part) > time(); |
$res->duedate($part) > time(); |
} |
} |
|
|
|
sub graceEndsUnder24Hours { |
|
my $res = shift; |
|
my $part = shift; |
|
my $status = $res->status($part); |
|
my $now = time(); |
|
|
|
return ($status == $res->OPEN() || |
|
$status == $res->TRIES_LEFT()) && |
|
$res->duedate($part) && $res->duedate($part) < $now && |
|
$res->overduedate($part) && $res->overduedate($part) < time()+(24*60*60) && |
|
$res->duedate($part) && $res->duedate($part) < $now+(24*60*60) && |
|
$res->overduedate($part) > $now; |
|
} |
|
|
sub advancedUser { |
sub advancedUser { |
return $env{'request.role.adv'}; |
return $env{'request.role.adv'}; |
Line 1120 sub render_resource {
|
Line 1155 sub render_resource {
|
} |
} |
|
|
# Decide what to display |
# Decide what to display |
$result .= "$newBranchText$linkopen$icon$linkclose"; |
$result .= "$newBranchText$linkopen$icon"; |
|
|
my $curMarkerBegin = ''; |
my $curMarkerBegin = ''; |
my $curMarkerEnd = ''; |
my $curMarkerEnd = ''; |
Line 1160 sub render_resource {
|
Line 1195 sub render_resource {
|
$linkopen = "<a href=\"$link\">"; |
$linkopen = "<a href=\"$link\">"; |
} |
} |
} |
} |
$result .= "$curMarkerBegin$linkopen$title$partLabel$linkclose$curMarkerEnd$editmapLink$nonLinkedText</td>"; |
$result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$linkclose$editmapLink$nonLinkedText</td>"; |
|
|
return $result; |
return $result; |
} |
} |
Line 1253 sub render_long_status {
|
Line 1288 sub render_long_status {
|
if (dueInLessThan24Hours($resource, $part)) { |
if (dueInLessThan24Hours($resource, $part)) { |
$color = $hurryUpColor; |
$color = $hurryUpColor; |
$info = ' title="'.&mt('Due in less than 24 hours!').'"'; |
$info = ' title="'.&mt('Due in less than 24 hours!').'"'; |
|
} elsif (graceEndsUnder24Hours($resource, $part)) { |
|
$color = $hurryUpColor; |
|
$info = ' title="'.&mt('Grace period ends in less than 24 hours!').'"'; |
} elsif (lastTry($resource, $part)) { |
} elsif (lastTry($resource, $part)) { |
unless (($resource->problemstatus($part) eq 'no') || |
unless (($resource->problemstatus($part) eq 'no') || |
($resource->problemstatus($part) eq 'no_feedback_ever')) { |
($resource->problemstatus($part) eq 'no_feedback_ever')) { |
Line 1379 sub cmp_title {
|
Line 1417 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 1572 sub render {
|
Line 1614 sub render {
|
my $curRes; |
my $curRes; |
my $foundJump = 0; |
my $foundJump = 0; |
my $counter = 0; |
my $counter = 0; |
|
|
while (($curRes = $mapIterator->next()) && !$foundJump) { |
while (($curRes = $mapIterator->next()) && !$foundJump) { |
if (ref($curRes)) { $counter++; } |
if (ref($curRes)) { $counter++; } |
|
# Speed up display after course initialization |
|
# when $jump is empty. Note: we still need |
|
# $counter to be 1 in that case if there is at |
|
# least one resource. |
|
last if (($jump eq '') && ($counter)); |
|
|
if (ref($curRes) && $jump eq $curRes->symb()) { |
if (ref($curRes) && $jump eq $curRes->symb()) { |
|
|
# This is why we have to use the main iterator instead of the |
# This is why we have to use the main iterator instead of the |
Line 1594 sub render {
|
Line 1641 sub render {
|
my $printKey = $args->{'printKey'}; |
my $printKey = $args->{'printKey'}; |
my $printCloseAll = $args->{'printCloseAll'}; |
my $printCloseAll = $args->{'printCloseAll'}; |
if (!defined($printCloseAll)) { $printCloseAll = 1; } |
if (!defined($printCloseAll)) { $printCloseAll = 1; } |
|
|
# Print key? |
# Print key? |
if ($printKey) { |
if ($printKey) { |
$result .= '<table border="0" cellpadding="2" cellspacing="0">'; |
my $location = &Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
$result.='<tr><td align="right" valign="bottom">Key: </td>'; |
$legend = '<div class="LC_navtools">'."\n". |
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
'<span class="LC_middle LC_right">'.&mt('Key').':</span>'. |
if ($navmap->{LAST_CHECK}) { |
'<span class="LC_middle LC_center"> '. |
$result .= |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('Unread Discussion'). |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('New discussion since').' '. |
' '. |
strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). |
'<img src="'.$location.'/feedback.gif" alt="" /> '. |
'</td><td align="center" valign="bottom"> '. |
&mt('New message (click to open)'). |
'<img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)').'<p>'. |
'</span></div>'. |
'</td>'; |
'<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n"; |
} else { |
|
$result .= '<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)'). |
|
'</td>'; |
|
} |
|
|
|
$result .= '</tr></table>'; |
|
} |
} |
|
|
if ($printCloseAll && !$args->{'resource_no_folder_link'}) { |
if ($printCloseAll && !$args->{'resource_no_folder_link'}) { |
Line 1634 sub render {
|
Line 1673 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 1648 sub render {
|
Line 1687 sub render {
|
my $time=time; |
my $time=time; |
my $submit = &mt($markread); |
my $submit = &mt($markread); |
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" aria-hidden="true"> |
<form name="clearbubbles" method="post" action="/adm/feedback" aria-hidden="true"> |
<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 1665 END
|
Line 1704 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" /> |
END |
END |
} |
} |
} |
} |
$result .= <<END; |
$tools .= <<END; |
<input type="submit" value="$submit" class="LC_visually_hidden" tabindex="-1" disabled="disabled" /> |
<input type="submit" value="$submit" class="LC_visually_hidden" tabindex="-1" disabled="disabled" /> |
</form> |
</form> |
END |
END |
Line 1695 END
|
Line 1734 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 1723 END
|
Line 1754 END
|
$args->{'counter'} = 0; # counts the rows |
$args->{'counter'} = 0; # counts the rows |
$args->{'indentLevel'} = 0; |
$args->{'indentLevel'} = 0; |
$args->{'isNewBranch'} = 0; |
$args->{'isNewBranch'} = 0; |
$args->{'condensed'} = 0; |
$args->{'condensed'} = 0; |
|
$args->{'deeplinknolist'} = 0; |
|
|
my $location = &Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif"); |
my $location = &Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif"); |
$args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='$location' alt='' />"); |
$args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='$location' alt='' />"); |
Line 1898 END
|
Line 1930 END
|
|
|
# If this has been filtered out, continue on |
# If this has been filtered out, continue on |
if (!(&$filterFunc($curRes))) { |
if (!(&$filterFunc($curRes))) { |
|
if (!$userCanSeeHidden && !$curRes->randomout && $curRes->deeplinkout) { |
|
$args->{'deeplinknolist'} ++; |
|
} |
$args->{'isNewBranch'} = 0; # Don't falsely remember this |
$args->{'isNewBranch'} = 0; # Don't falsely remember this |
next; |
next; |
} |
} |
Line 1922 END
|
Line 1957 END
|
if ($userCanSeeHidden) { |
if ($userCanSeeHidden) { |
$args->{'mapHiddenDeepLink'} = 1; |
$args->{'mapHiddenDeepLink'} = 1; |
} else { |
} else { |
|
$args->{'deeplinknolist'} ++; |
next; |
next; |
} |
} |
} else { |
} else { |
Line 1931 END
|
Line 1967 END
|
if ($userCanSeeHidden) { |
if ($userCanSeeHidden) { |
$args->{'mapUnlisted'} = 1; |
$args->{'mapUnlisted'} = 1; |
} else { |
} else { |
|
$args->{'deeplinknolist'} ++; |
next; |
next; |
} |
} |
} |
} |
Line 1944 END
|
Line 1981 END
|
} |
} |
|
|
$args->{'counter'}++; |
$args->{'counter'}++; |
|
unless ($tablestarted) { |
|
$result.=&Apache::loncommon::start_data_table("LC_tableOfContent"). |
|
&Apache::loncommon::start_data_table_header_row('LC_visually_hidden'). |
|
'<th>'.&mt('Resource or Folder').'</th>'. |
|
'<th>'.&mt('Alerts').'</th>'. |
|
'<th>'.&mt('Status Icon').'</th>'. |
|
'<th>'.&mt('Date/Completion Status').'</th>'. |
|
&Apache::loncommon::end_data_table_row()."\n"; |
|
$tablestarted = 1; |
|
} |
|
|
# Does it have multiple parts? |
# Does it have multiple parts? |
$args->{'multipart'} = 0; |
$args->{'multipart'} = 0; |
Line 2094 END
|
Line 2141 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 2109 END
|
Line 2162 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 |
Line 2127 if (location.href.indexOf('#curloc')==-1
|
Line 2182 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 2148 sub show_linkitems_toolbar {
|
Line 2214 sub show_linkitems_toolbar {
|
if (ref($args->{'linkitems'}) eq 'HASH') { |
if (ref($args->{'linkitems'}) eq 'HASH') { |
my $numlinks = scalar(keys(%{$args->{'linkitems'}})); |
my $numlinks = scalar(keys(%{$args->{'linkitems'}})); |
if ($numlinks > 1) { |
if ($numlinks > 1) { |
$result = '<td>'. |
$result = '<div class="LC_navtools">'. |
&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen', |
&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen', |
undef,'RAT'). |
undef,'RAT'). |
'</td>'. |
'</div><div class="LC_navtools"> '.&mt('Tools:').'</div>'; |
'<td> </td>'. |
|
'<td class="LC_middle">'.&mt('Tools:').'</td>'; |
|
} |
} |
$result .= '<td align="left">'."\n". |
$result .= '<div class="LC_navtools">'."\n". |
'<ul id="LC_toolbar">'; |
'<ul id="LC_toolbar">'; |
my @linkorder = ('firsthomework','everything','uncompleted', |
my @linkorder = ('firsthomework','everything','uncompleted', |
'changefolder','clearbubbles','printout','edittoplevel'); |
'changefolder','clearbubbles','printout','edittoplevel'); |
Line 2183 sub show_linkitems_toolbar {
|
Line 2247 sub show_linkitems_toolbar {
|
} |
} |
} |
} |
$result .= '</ul>'. |
$result .= '</ul>'. |
'</td>'; |
'</div>'; |
if (($numlinks==1) && (exists($args->{'linkitems'}{'edittoplevel'}))) { |
if (($numlinks==1) && (exists($args->{'linkitems'}{'edittoplevel'}))) { |
$result .= '<td><a href="'.$args->{'linkitems'}{'edittoplevel'}{'cmd'}.'">'. |
$result .= '<div class="LC_navtools">'. |
&mt('Content Editor').'</a></td>'; |
' <a href="'.$args->{'linkitems'}{'edittoplevel'}{'cmd'}.'">'. |
|
&mt('Content Editor').'</a></div>'; |
} |
} |
} |
} |
if ($args->{'sort_html'}) { |
if ($args->{'sort_html'}) { |
$result .= '<td> </td><td> </td><td> </td>'. |
$result .= '<div class="LC_navtools"> '. |
'<td align="right">'.$args->{'sort_html'}.'</td>'; |
$args->{'sort_html'}.'</div>'; |
} |
} |
} |
} |
if ($result) { |
if ($result) { |
$result = "<table><tr>$result</tr></table>"; |
$result = '<div class="LC_navtools">'.$result.'</div>'."\n". |
|
'<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n"; |
} |
} |
return $result; |
return $result; |
} |
} |
Line 2353 sub new {
|
Line 2419 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 { |
Line 3058 sub parmval_real {
|
Line 3125 sub parmval_real {
|
} |
} |
|
|
sub recurseup_maps { |
sub recurseup_maps { |
my ($self,$mapname,$getsymb) = @_; |
my ($self,$mapname,$getsymb,$inclusive) = @_; |
my @recurseup; |
my @recurseup; |
if ($mapname) { |
if ($mapname) { |
my $res = $self->getResourceByUrl($mapname); |
my $res = $self->getResourceByUrl($mapname); |
Line 3072 sub recurseup_maps {
|
Line 3139 sub recurseup_maps {
|
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); |
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); |
} |
} |
} |
} |
|
if ($inclusive) { |
|
if ($getsymb) { |
|
unshift(@recurseup,$res->symb()); |
|
} else { |
|
unshift(@recurseup,$mapname); |
|
} |
|
} |
} |
} |
} |
} |
return @recurseup; |
return @recurseup; |
Line 5140 sub awarded {
|
Line 5214 sub awarded {
|
if (!defined($part)) { $part = '0'; } |
if (!defined($part)) { $part = '0'; } |
return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->{SYMB}}->{'resource.'.$part.'.awarded'}; |
return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->{SYMB}}->{'resource.'.$part.'.awarded'}; |
} |
} |
|
sub latefrac { |
|
my $self = shift; my $part = shift; |
|
$self->{NAV_MAP}->get_user_data(); |
|
if (!defined($part)) { $part = '0'; } |
|
return $self->{NAV_MAP}->{STUDENT_DATA}->{$self->{SYMB}}->{'resource.'.$part.'.latefrac'}; |
|
} |
sub taskversion { |
sub taskversion { |
my $self = shift; my $part = shift; |
my $self = shift; my $part = shift; |
$self->{NAV_MAP}->get_user_data(); |
$self->{NAV_MAP}->get_user_data(); |
Line 5229 sub opendate {
|
Line 5309 sub opendate {
|
} |
} |
return $opendate; |
return $opendate; |
} |
} |
|
sub overduedate { |
|
my ($self,$part) = @_; |
|
my $duedate = $self->parmval("duedate", $part); |
|
my $overduedate; |
|
if ($duedate) { |
|
my $grace = $self->parmval("grace", $part); |
|
if ($grace) { |
|
my $grace_end = (split(/,/,$grace))[-1]; |
|
my ($offset) = split(/:/,$grace_end,2); |
|
if ($offset > 0) { |
|
$overduedate = $offset + $duedate; |
|
} |
|
} |
|
} |
|
return $overduedate; |
|
} |
|
sub partial_credit_overdue { |
|
my ($self,$part) = @_; |
|
my $reduction; |
|
my $duedate = $self->parmval("duedate", $part); |
|
if ($duedate) { |
|
my $grace = $self->parmval("grace",$part); |
|
if ($grace) { |
|
my $lateness = time - $duedate; |
|
if ($lateness > 0) { |
|
my ($start,$end,$startfrac,$endfrac,$usegrad); |
|
$start = 0; |
|
$startfrac = 1.0; |
|
$usegrad = 0; |
|
foreach my $item (split(/,/,$grace)) { |
|
my ($offset,$frac,$grad) = split(/:/,$item); |
|
if ($lateness > $offset) { |
|
$start = $offset; |
|
$startfrac = $frac; |
|
next; |
|
} elsif ($lateness <= $offset) { |
|
$end = $offset; |
|
$endfrac = $frac; |
|
$usegrad = $grad; |
|
last; |
|
} |
|
} |
|
if ($end) { |
|
if (($end == $start) || ($startfrac == $endfrac)) { |
|
$reduction = $endfrac; |
|
} elsif ($end - $start > 0) { |
|
if (($endfrac <= 1.0) && ($endfrac >= 0)) { |
|
$reduction = $endfrac; |
|
if ($usegrad) { |
|
my $decline = $startfrac - $endfrac; |
|
my $fraction = ($lateness - $start)/($end - $start); |
|
if (($fraction <= 1) && ($fraction >= 0)) { |
|
my $value = $startfrac - ($decline*$fraction); |
|
$reduction = sprintf("%.2f", $value); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return $reduction; |
|
} |
|
|
sub problemstatus { |
sub problemstatus { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
my $problemstatus = $self->parmval("problemstatus", $part); |
my $problemstatus = $self->parmval("problemstatus", $part); |
Line 5807 sub getDateStatus {
|
Line 5952 sub getDateStatus {
|
|
|
my $open = $self->opendate($part); |
my $open = $self->opendate($part); |
my $due = $self->duedate($part); |
my $due = $self->duedate($part); |
|
my $overdue = $self->overduedate($part); |
my $answer = $self->answerdate($part); |
my $answer = $self->answerdate($part); |
|
|
if (!$open && !$due && !$answer) { |
if (!$open && !$due && !$answer) { |
Line 5816 sub getDateStatus {
|
Line 5962 sub getDateStatus {
|
} |
} |
if (!$open || $now < $open) {return $self->OPEN_LATER} |
if (!$open || $now < $open) {return $self->OPEN_LATER} |
if (!$due || $now < $due) {return $self->OPEN} |
if (!$due || $now < $due) {return $self->OPEN} |
|
if ($overdue && $now < $overdue) {return $self->OPEN} |
if ($answer && $now < $answer) {return $self->PAST_DUE_ANSWER_LATER} |
if ($answer && $now < $answer) {return $self->PAST_DUE_ANSWER_LATER} |
if ($answer) { return $self->ANSWER_OPEN; } |
if ($answer) { return $self->ANSWER_OPEN; } |
return PAST_DUE_NO_ANSWER; |
return PAST_DUE_NO_ANSWER; |
Line 6084 sub status {
|
Line 6231 sub status {
|
# If there's an answer date and we're past it, don't |
# If there's an answer date and we're past it, don't |
# suppress the feedback; student should know |
# suppress the feedback; student should know |
if ($self->duedate($part) && $self->duedate($part) < time() && |
if ($self->duedate($part) && $self->duedate($part) < time() && |
|
(!$self->overduedate($part) || $self->overduedate($part) < time()) && |
$self->answerdate($part) && $self->answerdate($part) < time()) { |
$self->answerdate($part) && $self->answerdate($part) < time()) { |
$suppressFeedback = 0; |
$suppressFeedback = 0; |
} |
} |