version 1.396, 2007/01/05 06:43:34
|
version 1.415.4.1, 2009/09/15 00:52:39
|
Line 36 use Apache::lonenc();
|
Line 36 use Apache::lonenc();
|
use Apache::lonlocal; |
use Apache::lonlocal; |
use Apache::lonnet; |
use Apache::lonnet; |
use POSIX qw (floor strftime); |
use POSIX qw (floor strftime); |
use Data::Dumper; # for debugging, not always |
|
use Time::HiRes qw( gettimeofday tv_interval ); |
use Time::HiRes qw( gettimeofday tv_interval ); |
use lib '/home/httpd/lib/perl/'; |
|
use LONCAPA; |
use LONCAPA; |
|
use DateTime(); |
|
|
# symbolic constants |
# symbolic constants |
sub SYMB { return 1; } |
sub SYMB { return 1; } |
Line 86 my %colormap =
|
Line 85 my %colormap =
|
$resObj->PARTIALLY_CORRECT => '#006600' |
$resObj->PARTIALLY_CORRECT => '#006600' |
); |
); |
# And a special case in the nav map; what to do when the assignment |
# And a special case in the nav map; what to do when the assignment |
# is not yet done and due in less then 24 hours |
# is not yet done and due in less than 24 hours |
my $hurryUpColor = "#FF0000"; |
my $hurryUpColor = "#FF0000"; |
|
|
sub close { |
sub close { |
Line 171 sub getLinkForResource {
|
Line 170 sub getLinkForResource {
|
if (defined($item)) { $res = $item; } |
if (defined($item)) { $res = $item; } |
} |
} |
|
|
return ($res->link(),$res->shown_symb()); |
if ($res) { |
|
return ($res->link(),$res->shown_symb()); |
|
} |
|
return; |
} |
} |
|
|
# Convenience function: This separates the logic of how to create |
# Convenience function: This separates the logic of how to create |
Line 185 sub getDescription {
|
Line 187 sub getDescription {
|
my $part = shift; |
my $part = shift; |
my $status = $res->status($part); |
my $status = $res->status($part); |
|
|
|
my $open = $res->opendate($part); |
|
my $due = $res->duedate($part); |
|
my $answer = $res->answerdate($part); |
|
|
if ($status == $res->NETWORK_FAILURE) { |
if ($status == $res->NETWORK_FAILURE) { |
return &mt("Having technical difficulties; please check status later"); |
return &mt("Having technical difficulties; please check status later"); |
} |
} |
Line 192 sub getDescription {
|
Line 198 sub getDescription {
|
return &mt("Not currently assigned."); |
return &mt("Not currently assigned."); |
} |
} |
if ($status == $res->OPEN_LATER) { |
if ($status == $res->OPEN_LATER) { |
return "Open " . timeToHumanString($res->opendate($part),'start'); |
return &mt("Open ") .timeToHumanString($open,'start'); |
} |
} |
if ($status == $res->OPEN) { |
if ($status == $res->OPEN) { |
if ($res->duedate($part)) { |
if ($due) { |
return &mt("Due")." " .timeToHumanString($res->duedate($part),'end'); |
if ($res->is_practice()) { |
|
return &mt("Closes ")." " .timeToHumanString($due,'start'); |
|
} else { |
|
return &mt("Due")." " .timeToHumanString($due,'end'); |
|
} |
} else { |
} else { |
return &mt("Open, no due date"); |
return &mt("Open, no due date"); |
} |
} |
} |
} |
if ($status == $res->PAST_DUE_ANSWER_LATER) { |
if ($status == $res->PAST_DUE_ANSWER_LATER) { |
return &mt("Answer open")." " . timeToHumanString($res->answerdate($part),'start'); |
return &mt("Answer open")." " .timeToHumanString($answer,'start'); |
} |
} |
if ($status == $res->PAST_DUE_NO_ANSWER) { |
if ($status == $res->PAST_DUE_NO_ANSWER) { |
return &mt("Was due")." " . timeToHumanString($res->duedate($part),'end'); |
if ($res->is_practice()) { |
|
return &mt("Closed")." " . timeToHumanString($due,'start'); |
|
} else { |
|
return &mt("Was due")." " . timeToHumanString($due,'end'); |
|
} |
} |
} |
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') { |
Line 222 sub getDescription {
|
Line 236 sub getDescription {
|
my $maxtries = $res->maxtries($part); |
my $maxtries = $res->maxtries($part); |
my $triesString = ""; |
my $triesString = ""; |
if ($tries && $maxtries) { |
if ($tries && $maxtries) { |
$triesString = "<font size=\"-1\"><i>($tries of $maxtries tries used)</i></font>"; |
$triesString = '<font size="-1"><i>('.&mt('[_1] of [quant,_2,try,tries] used',$tries,$maxtries).')</i></font>'; |
if ($maxtries > 1 && $maxtries - $tries == 1) { |
if ($maxtries > 1 && $maxtries - $tries == 1) { |
$triesString = "<b>$triesString</b>"; |
$triesString = "<b>$triesString</b>"; |
} |
} |
} |
} |
if ($res->duedate($part)) { |
if ($due) { |
return &mt("Due")." " . timeToHumanString($res->duedate($part),'end') . |
return &mt("Due")." " . timeToHumanString($due,'end') . |
" $triesString"; |
" $triesString"; |
} else { |
} else { |
return &mt("No due date")." $triesString"; |
return &mt("No due date")." $triesString"; |
Line 239 sub getDescription {
|
Line 253 sub getDescription {
|
} |
} |
} |
} |
|
|
# Convenience function, so others can use it: Is the problem due in less then |
# Convenience function, so others can use it: Is the problem due in less than |
# 24 hours, and still can be done? |
# 24 hours, and still can be done? |
|
|
sub dueInLessThan24Hours { |
sub dueInLessThan24Hours { |
Line 254 sub dueInLessThan24Hours {
|
Line 268 sub dueInLessThan24Hours {
|
} |
} |
|
|
# 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 then 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? |
sub lastTry { |
sub lastTry { |
my $res = shift; |
my $res = shift; |
my $part = shift; |
my $part = shift; |
Line 295 sub timeToHumanString {
|
Line 309 sub timeToHumanString {
|
} |
} |
my $now = time(); |
my $now = time(); |
|
|
my @time = localtime($time); |
|
my @now = localtime($now); |
|
|
|
# Positive = future |
# Positive = future |
my $delta = $time - $now; |
my $delta = $time - $now; |
|
|
Line 323 sub timeToHumanString {
|
Line 334 sub timeToHumanString {
|
my $tense = $inPast ? " ago" : ""; |
my $tense = $inPast ? " ago" : ""; |
my $prefix = $inPast ? "" : "in "; |
my $prefix = $inPast ? "" : "in "; |
|
|
# Less then a minute |
# Less than a minute |
if ( $delta < $minute ) { |
if ( $delta < $minute ) { |
if ($delta == 1) { return "${prefix}1 second$tense"; } |
if ($delta == 1) { return "${prefix}1 second$tense"; } |
return "$prefix$delta seconds$tense"; |
return "$prefix$delta seconds$tense"; |
} |
} |
|
|
# Less then an hour |
# Less than an hour |
if ( $delta < $hour ) { |
if ( $delta < $hour ) { |
# If so, use minutes |
# If so, use minutes |
my $minutes = floor($delta / 60); |
my $minutes = floor($delta / 60); |
Line 337 sub timeToHumanString {
|
Line 348 sub timeToHumanString {
|
return "$prefix$minutes minutes$tense"; |
return "$prefix$minutes minutes$tense"; |
} |
} |
|
|
# Is it less then 24 hours away? If so, |
# Is it less than 24 hours away? If so, |
# display hours + minutes |
# display hours + minutes |
if ( $delta < $hour * 24) { |
if ( $delta < $hour * 24) { |
my $hours = floor($delta / $hour); |
my $hours = floor($delta / $hour); |
Line 356 sub timeToHumanString {
|
Line 367 sub timeToHumanString {
|
return "$prefix$hourString$minuteString$tense"; |
return "$prefix$hourString$minuteString$tense"; |
} |
} |
|
|
|
my $dt = DateTime->from_epoch(epoch => $time) |
|
->set_time_zone(&Apache::lonlocal::gettimezone()); |
|
|
# If there's a caller supplied format, use it. |
# If there's a caller supplied format, use it. |
|
|
if($format ne '') { |
if ($format ne '') { |
my $timeStr = strftime($format, localtime($time)); |
my $timeStr = $dt->strftime($format); |
return $timeStr.&Apache::lonlocal::gettimezone($time); |
return $timeStr.' ('.$dt->time_zone_short_name().')'; |
} |
} |
|
|
# Less then 5 days away, display day of the week and |
# Less than 5 days away, display day of the week and |
# HH:MM |
# HH:MM |
|
|
if ( $delta < $day * 5 ) { |
if ( $delta < $day * 5 ) { |
my $timeStr = strftime("%A, %b %e at %I:%M %P", localtime($time)); |
my $timeStr = $dt->strftime("%A, %b %e at %I:%M %P (%Z)"); |
$timeStr =~ s/12:00 am/00:00/; |
$timeStr =~ s/12:00 am/00:00/; |
$timeStr =~ s/12:00 pm/noon/; |
$timeStr =~ s/12:00 pm/noon/; |
return ($inPast ? "last " : "this ") . |
return ($inPast ? "last " : "this ") . |
$timeStr.&Apache::lonlocal::gettimezone($time); |
$timeStr; |
} |
} |
|
|
my $conjunction='on'; |
my $conjunction='on'; |
Line 381 sub timeToHumanString {
|
Line 395 sub timeToHumanString {
|
$conjunction='by'; |
$conjunction='by'; |
} |
} |
# Is it this year? |
# Is it this year? |
if ( $time[5] == $now[5]) { |
my $dt_now = DateTime->from_epoch(epoch => $now) |
|
->set_time_zone(&Apache::lonlocal::gettimezone()); |
|
if ( $dt->year() == $dt_now->year()) { |
# Return on Month Day, HH:MM meridian |
# Return on Month Day, HH:MM meridian |
my $timeStr = strftime("$conjunction %A, %b %e at %I:%M %P", localtime($time)); |
my $timeStr = $dt->strftime("$conjunction %A, %b %e at %I:%M %P (%Z)"); |
$timeStr =~ s/12:00 am/00:00/; |
$timeStr =~ s/12:00 am/00:00/; |
$timeStr =~ s/12:00 pm/noon/; |
$timeStr =~ s/12:00 pm/noon/; |
return $timeStr.&Apache::lonlocal::gettimezone($time); |
return $timeStr; |
} |
} |
|
|
# Not this year, so show the year |
# Not this year, so show the year |
my $timeStr = strftime("$conjunction %A, %b %e %Y at %I:%M %P", localtime($time)); |
my $timeStr = |
|
$dt->strftime("$conjunction %A, %b %e %Y at %I:%M %P (%Z)"); |
$timeStr =~ s/12:00 am/00:00/; |
$timeStr =~ s/12:00 am/00:00/; |
$timeStr =~ s/12:00 pm/noon/; |
$timeStr =~ s/12:00 pm/noon/; |
return $timeStr.&Apache::lonlocal::gettimezone($time); |
return $timeStr; |
} |
} |
} |
} |
|
|
Line 428 to compute due to the amount of data tha
|
Line 445 to compute due to the amount of data tha
|
processed. |
processed. |
|
|
Apache::lonnavmaps provides an object model for manipulating this |
Apache::lonnavmaps provides an object model for manipulating this |
information in a higher-level fashion then directly manipulating |
information in a higher-level fashion than directly manipulating |
the hash. It also provides access to several auxilary functions |
the hash. It also provides access to several auxilary functions |
that aren't necessarily stored in the Big Hash, but are a per- |
that aren't necessarily stored in the Big Hash, but are a per- |
resource sort of value, like whether there is any feedback on |
resource sort of value, like whether there is any feedback on |
Line 474 Apache::lonnavmaps::render({}).
|
Line 491 Apache::lonnavmaps::render({}).
|
=head2 Overview of Columns |
=head2 Overview of Columns |
|
|
The renderer will build an HTML table for the navmap and return |
The renderer will build an HTML table for the navmap and return |
it. The table is consists of several columns, and a row for each |
it. The table consists of several columns, and a row for each |
resource (or possibly each part). You tell the renderer how many |
resource (or possibly each part). You tell the renderer how many |
columns to create and what to place in each column, optionally using |
columns to create and what to place in each column, optionally using |
one or more of the prepared columns, and the renderer will assemble |
one or more of the prepared columns, and the renderer will assemble |
Line 605 instruct the renderer to render only a p
|
Line 622 instruct the renderer to render only a p
|
the source of the map you want to process, like |
the source of the map you want to process, like |
'/res/103/jerf/navmap.course.sequence'. |
'/res/103/jerf/navmap.course.sequence'. |
|
|
|
=item * B<include_top_level_map>: default: false |
|
|
|
If you need to include the top level map (meaning the course) in the |
|
rendered output set this to true |
|
|
=item * B<navmap>: default: constructs one from %env |
=item * B<navmap>: default: constructs one from %env |
|
|
A reference to a navmap, used only if an iterator is not passed in. If |
A reference to a navmap, used only if an iterator is not passed in. If |
Line 832 sub render_resource {
|
Line 854 sub render_resource {
|
if (!$resource->condval()) { |
if (!$resource->condval()) { |
$nonLinkedText .= ' <i>('.&mt('conditionally hidden').')</i> '; |
$nonLinkedText .= ' <i>('.&mt('conditionally hidden').')</i> '; |
} |
} |
|
if (($resource->is_practice()) && ($resource->is_raw_problem())) { |
|
$nonLinkedText .=' <font color="green"><b>'.&mt('not graded').'</b></font>'; |
|
} |
|
|
# We're done preparing and finally ready to start the rendering |
# We're done preparing and finally ready to start the rendering |
my $result = "<td align='left' valign='middle'>"; |
my $result = "<td align='left' valign='middle'>"; |
|
|
Line 975 sub render_long_status {
|
Line 1000 sub render_long_status {
|
$params->{'multipart'} && $part eq "0"; |
$params->{'multipart'} && $part eq "0"; |
|
|
my $color; |
my $color; |
if ($resource->is_problem()) { |
if ($resource->is_problem() || $resource->is_practice()) { |
$color = $colormap{$resource->status}; |
$color = $colormap{$resource->status}; |
|
|
if (dueInLessThan24Hours($resource, $part) || |
if (dueInLessThan24Hours($resource, $part) || |
Line 985 sub render_long_status {
|
Line 1010 sub render_long_status {
|
} |
} |
|
|
if ($resource->kind() eq "res" && |
if ($resource->kind() eq "res" && |
$resource->is_problem() && |
($resource->is_problem() || $resource->is_practice()) && |
!$firstDisplayed) { |
!$firstDisplayed) { |
if ($color) {$result .= "<font color=\"$color\"><b>"; } |
if ($color) {$result .= "<font color=\"$color\"><b>"; } |
$result .= getDescription($resource, $part); |
$result .= getDescription($resource, $part); |
if ($color) {$result .= "</b></font>"; } |
if ($color) {$result .= "</b></font>"; } |
} |
} |
if ($resource->is_map() && advancedUser() && $resource->randompick()) { |
if ($resource->is_map() && &advancedUser() && $resource->randompick()) { |
$result .= '(randomly select ' . $resource->randompick() .')'; |
$result .= &mt('(randomly select [_1])', $resource->randompick()); |
|
} |
|
if ($resource->is_map() && &advancedUser() && $resource->randomorder()) { |
|
$result .= &mt('(randomly ordered)'); |
} |
} |
|
|
# Debugging code |
# Debugging code |
Line 1027 my %statusStrings =
|
Line 1055 my %statusStrings =
|
); |
); |
my @statuses = ($resObj->CORRECT, $resObj->ATTEMPTED, $resObj->INCORRECT, $resObj->OPEN, $resObj->CLOSED, $resObj->ERROR); |
my @statuses = ($resObj->CORRECT, $resObj->ATTEMPTED, $resObj->INCORRECT, $resObj->OPEN, $resObj->CLOSED, $resObj->ERROR); |
|
|
use Data::Dumper; |
|
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_problem() && !$resource->contains_problem) { return '<td></td>'; } |
Line 1155 sub render {
|
Line 1182 sub render {
|
if (!defined($navmap)) { |
if (!defined($navmap)) { |
$navmap = Apache::lonnavmaps::navmap->new(); |
$navmap = Apache::lonnavmaps::navmap->new(); |
if (!defined($navmap)) { |
if (!defined($navmap)) { |
# no londer in course |
# no longer in course |
return '<span class="LC_error">'.&mt('No course selected').'</span><br /> |
return '<span class="LC_error">'.&mt('No course selected').'</span><br /> |
<a href="/adm/roles">'.&mt('Select a course').'</a><br />'; |
<a href="/adm/roles">'.&mt('Select a course').'</a><br />'; |
} |
} |
Line 1223 sub render {
|
Line 1250 sub render {
|
# Step 1: Check to see if we have a navmap |
# Step 1: Check to see if we have a navmap |
if (!defined($navmap)) { |
if (!defined($navmap)) { |
$navmap = Apache::lonnavmaps::navmap->new(); |
$navmap = Apache::lonnavmaps::navmap->new(); |
|
if (!defined($navmap)) { |
|
# no longer in course |
|
return '<span class="LC_error">'.&mt('No course selected').'</span><br /> |
|
<a href="/adm/roles">'.&mt('Select a course').'</a><br />'; |
|
} |
} |
} |
|
|
# See if we're being passed a specific map |
# See if we're being passed a specific map |
Line 1234 sub render {
|
Line 1266 sub render {
|
|
|
$args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition); |
$args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition); |
} else { |
} else { |
$args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition); |
$args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition,undef,$args->{'include_top_level_map'}); |
} |
} |
} |
} |
|
|
Line 1271 sub render {
|
Line 1303 sub render {
|
# Print key? |
# Print key? |
if ($printKey) { |
if ($printKey) { |
$result .= '<table border="0" cellpadding="2" cellspacing="0">'; |
$result .= '<table border="0" cellpadding="2" cellspacing="0">'; |
my $date=localtime; |
|
$result.='<tr><td align="right" valign="bottom">Key: </td>'; |
$result.='<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}) { |
Line 1715 ENDBLOCK
|
Line 1746 ENDBLOCK
|
$result.='} |
$result.='} |
</script> |
</script> |
<form name="linkitems" method="post"> |
<form name="linkitems" method="post"> |
<nobr><select name="toplink">'."\n"; |
<span class="LC_nobreak"><select name="toplink">'."\n"; |
foreach my $link (@linkorder) { |
foreach my $link (@linkorder) { |
if (defined($linkitems->{$link})) { |
if (defined($linkitems->{$link})) { |
if ($linkitems->{$link}{'text'} ne '') { |
if ($linkitems->{$link}{'text'} ne '') { |
Line 1726 ENDBLOCK
|
Line 1757 ENDBLOCK
|
} |
} |
$result .= '</select> <input type="button" name="chgnav" |
$result .= '</select> <input type="button" name="chgnav" |
value="Go" onClick="javascript:changeNavDisplay()" /> |
value="Go" onClick="javascript:changeNavDisplay()" /> |
</nobr></form></td>'."\n"; |
</span></form></td>'."\n"; |
|
|
return $result; |
return $result; |
} |
} |
Line 1802 See iterator documentation below.
|
Line 1833 See iterator documentation below.
|
use strict; |
use strict; |
use GDBM_File; |
use GDBM_File; |
use Apache::lonnet; |
use Apache::lonnet; |
|
use LONCAPA; |
|
|
sub new { |
sub new { |
# magic invocation to create a class instance |
# magic invocation to create a class instance |
Line 2057 sub discussion_info {
|
Line 2089 sub discussion_info {
|
|
|
my $ressymb = $self->wrap_symb($symb); |
my $ressymb = $self->wrap_symb($symb); |
# keys used to store bulletinboard postings use 'unwrapped' symb. |
# keys used to store bulletinboard postings use 'unwrapped' symb. |
my $discsymb = $self->unwrap_symb($ressymb); |
my $discsymb = &escape($self->unwrap_symb($ressymb)); |
my $version = $self->{DISCUSSION_DATA}{'version:'.$discsymb}; |
my $version = $self->{DISCUSSION_DATA}{'version:'.$discsymb}; |
if (!$version) { return; } |
if (!$version) { return; } |
|
|
Line 2197 the given map. This is one of the proper
|
Line 2229 the given map. This is one of the proper
|
|
|
# The strategy here is to cache the resource objects, and only construct them |
# The strategy here is to cache the resource objects, and only construct them |
# as we use them. The real point is to prevent reading any more from the tied |
# as we use them. The real point is to prevent reading any more from the tied |
# hash then we have to, which should hopefully alleviate speed problems. |
# hash than we have to, which should hopefully alleviate speed problems. |
|
|
sub getById { |
sub getById { |
my $self = shift; |
my $self = shift; |
Line 2271 sub finishResource {
|
Line 2303 sub finishResource {
|
# the actual lookup; parmval caches the results. |
# the actual lookup; parmval caches the results. |
sub parmval { |
sub parmval { |
my $self = shift; |
my $self = shift; |
my ($what,$symb)=@_; |
my ($what,$symb,$recurse)=@_; |
my $hashkey = $what."|||".$symb; |
my $hashkey = $what."|||".$symb; |
|
|
if (defined($self->{PARM_CACHE}->{$hashkey})) { |
if (defined($self->{PARM_CACHE}->{$hashkey})) { |
return $self->{PARM_CACHE}->{$hashkey}; |
if (ref($self->{PARM_CACHE}->{$hashkey}) eq 'ARRAY') { |
|
if (defined($self->{PARM_CACHE}->{$hashkey}->[0])) { |
|
if (wantarray) { |
|
return @{$self->{PARM_CACHE}->{$hashkey}}; |
|
} else { |
|
return $self->{PARM_CACHE}->{$hashkey}->[0]; |
|
} |
|
} |
|
} else { |
|
return $self->{PARM_CACHE}->{$hashkey}; |
|
} |
} |
} |
|
my $result = $self->parmval_real($what, $symb, $recurse); |
my $result = $self->parmval_real($what, $symb); |
|
$self->{PARM_CACHE}->{$hashkey} = $result; |
$self->{PARM_CACHE}->{$hashkey} = $result; |
return $result; |
if (wantarray) { |
|
return @{$result}; |
|
} |
|
return $result->[0]; |
} |
} |
|
|
sub parmval_real { |
sub parmval_real { |
Line 2301 sub parmval_real {
|
Line 2345 sub parmval_real {
|
my $uname=$env{'user.name'}; |
my $uname=$env{'user.name'}; |
my $udom=$env{'user.domain'}; |
my $udom=$env{'user.domain'}; |
|
|
unless ($symb) { return ''; } |
unless ($symb) { return ['']; } |
my $result=''; |
my $result=''; |
|
|
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
Line 2333 sub parmval_real {
|
Line 2377 sub parmval_real {
|
|
|
# ---------------------------------------------------------- first, check user |
# ---------------------------------------------------------- first, check user |
if ($uname and defined($useropt)) { |
if ($uname and defined($useropt)) { |
if (defined($$useropt{$courselevelr})) { return $$useropt{$courselevelr}; } |
if (defined($$useropt{$courselevelr})) { return [$$useropt{$courselevelr},'resource']; } |
if (defined($$useropt{$courselevelm})) { return $$useropt{$courselevelm}; } |
if (defined($$useropt{$courselevelm})) { return [$$useropt{$courselevelm},'map']; } |
if (defined($$useropt{$courselevel})) { return $$useropt{$courselevel}; } |
if (defined($$useropt{$courselevel})) { return [$$useropt{$courselevel},'course']; } |
} |
} |
|
|
# ------------------------------------------------------- second, check course |
# ------------------------------------------------------- second, check course |
if ($cgroup ne '' and defined($courseopt)) { |
if ($cgroup ne '' and defined($courseopt)) { |
if (defined($$courseopt{$grplevelr})) { return $$courseopt{$grplevelr}; } |
if (defined($$courseopt{$grplevelr})) { return [$$courseopt{$grplevelr},'resource']; } |
if (defined($$courseopt{$grplevelm})) { return $$courseopt{$grplevelm}; } |
if (defined($$courseopt{$grplevelm})) { return [$$courseopt{$grplevelm},'map']; } |
if (defined($$courseopt{$grplevel})) { return $$courseopt{$grplevel}; } |
if (defined($$courseopt{$grplevel})) { return [$$courseopt{$grplevel},'course']; } |
} |
} |
|
|
if ($csec and defined($courseopt)) { |
if ($csec and defined($courseopt)) { |
if (defined($$courseopt{$seclevelr})) { return $$courseopt{$seclevelr}; } |
if (defined($$courseopt{$seclevelr})) { return [$$courseopt{$seclevelr},'resource']; } |
if (defined($$courseopt{$seclevelm})) { return $$courseopt{$seclevelm}; } |
if (defined($$courseopt{$seclevelm})) { return [$$courseopt{$seclevelm},'map']; } |
if (defined($$courseopt{$seclevel})) { return $$courseopt{$seclevel}; } |
if (defined($$courseopt{$seclevel})) { return [$$courseopt{$seclevel},'course']; } |
} |
} |
|
|
if (defined($courseopt)) { |
if (defined($courseopt)) { |
if (defined($$courseopt{$courselevelr})) { return $$courseopt{$courselevelr}; } |
if (defined($$courseopt{$courselevelr})) { return [$$courseopt{$courselevelr},'resource']; } |
} |
} |
|
|
# ----------------------------------------------------- third, check map parms |
# ----------------------------------------------------- third, check map parms |
|
|
my $thisparm=$$parmhash{$symbparm}; |
my $thisparm=$$parmhash{$symbparm}; |
if (defined($thisparm)) { return $thisparm; } |
if (defined($thisparm)) { return [$thisparm,'map']; } |
|
|
# ----------------------------------------------------- fourth , check default |
# ----------------------------------------------------- fourth , check default |
|
|
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); |
if (defined($default)) { return $default} |
if (defined($default)) { return [$default,'resource']} |
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat); |
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat); |
if (defined($default)) { return $default} |
if (defined($default)) { return [$default,'resource']} |
|
|
# --------------------------------------------------- fifth, check more course |
# --------------------------------------------------- fifth, check more course |
if (defined($courseopt)) { |
if (defined($courseopt)) { |
if (defined($$courseopt{$courselevelm})) { return $$courseopt{$courselevelm}; } |
if (defined($$courseopt{$courselevelm})) { return [$$courseopt{$courselevelm},'map']; } |
if (defined($$courseopt{$courselevel})) { return $$courseopt{$courselevel}; } |
if (defined($$courseopt{$courselevel})) { |
|
my $ret = [$$courseopt{$courselevel},'course']; |
|
return $ret; |
|
} |
} |
} |
|
|
# --------------------------------------------------- sixth , cascade up parts |
# --------------------------------------------------- sixth , cascade up parts |
|
|
my ($space,@qualifier)=split(/\./,$rwhat); |
my ($space,@qualifier)=split(/\./,$rwhat); |
Line 2384 sub parmval_real {
|
Line 2429 sub parmval_real {
|
my $id=pop(@parts); |
my $id=pop(@parts); |
my $part=join('_',@parts); |
my $part=join('_',@parts); |
if ($part eq '') { $part='0'; } |
if ($part eq '') { $part='0'; } |
my $partgeneral=$self->parmval($part.".$qualifier",$symb,1); |
my @partgeneral=$self->parmval($part.".$qualifier",$symb,1); |
if (defined($partgeneral)) { return $partgeneral; } |
if (defined($partgeneral[0])) { return \@partgeneral; } |
} |
} |
if ($recurse) { return undef; } |
if ($recurse) { return []; } |
my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$what); |
my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat); |
if (defined($pack_def)) { return $pack_def; } |
if (defined($pack_def)) { return [$pack_def,'resource']; } |
return ''; |
return ['']; |
} |
} |
|
|
=pod |
=pod |
Line 2398 sub parmval_real {
|
Line 2443 sub parmval_real {
|
=item * B<getResourceByUrl>(url,multiple): |
=item * B<getResourceByUrl>(url,multiple): |
|
|
Retrieves a resource object by URL of the resource, unless the optional |
Retrieves a resource object by URL of the resource, unless the optional |
multiple parameter is included in wahich caes an array of resource |
multiple parameter is included in which case an array of resource |
objects is returned. If passed a resource object, it will simply return |
objects is returned. If passed a resource object, it will simply return |
it, so it is safe to use this method in code like |
it, so it is safe to use this method in code like |
"$res = $navmap->getResourceByUrl($res)" |
"$res = $navmap->getResourceByUrl($res)" |
Line 2433 all matching resources.
|
Line 2478 all matching resources.
|
|
|
=item * B<hasResource>(map, filterFunc, recursive, showall): |
=item * B<hasResource>(map, filterFunc, recursive, showall): |
|
|
Convience method for |
Convenience method for |
|
|
scalar(retrieveResources($map, $filterFunc, $recursive, 1, $showall)) > 0 |
scalar(retrieveResources($map, $filterFunc, $recursive, 1, $showall)) > 0 |
|
|
Line 2511 sub retrieveResources {
|
Line 2556 sub retrieveResources {
|
|
|
my @resources = (); |
my @resources = (); |
|
|
|
if (&$filterFunc($map)) { |
|
push(@resources, $map); |
|
} |
|
|
# Run down the iterator and collect the resources. |
# Run down the iterator and collect the resources. |
my $curRes; |
my $curRes; |
|
|
Line 2520 sub retrieveResources {
|
Line 2569 sub retrieveResources {
|
next; |
next; |
} |
} |
|
|
push @resources, $curRes; |
push(@resources, $curRes); |
|
|
if ($bailout) { |
if ($bailout) { |
return @resources; |
return @resources; |
Line 2667 be the tokens described above.
|
Line 2716 be the tokens described above.
|
|
|
Also note there is some old code floating around that trys to track |
Also note there is some old code floating around that trys to track |
the depth of the iterator to see when it's done; do not copy that |
the depth of the iterator to see when it's done; do not copy that |
code. It is difficult to get right and harder to understand then |
code. It is difficult to get right and harder to understand than |
this. They should be migrated to this new style. |
this. They should be migrated to this new style. |
|
|
=cut |
=cut |
Line 2851 sub next {
|
Line 2900 sub next {
|
$self->{HAVE_RETURNED_0} = 1; |
$self->{HAVE_RETURNED_0} = 1; |
return $self->{NAV_MAP}->getById('0.0'); |
return $self->{NAV_MAP}->getById('0.0'); |
} |
} |
|
if ($self->{RETURN_0} && !$self->{HAVE_RETURNED_0_BEGIN_MAP}) { |
|
$self->{HAVE_RETURNED_0_BEGIN_MAP} = 1; |
|
return $self->BEGIN_MAP(); |
|
} |
|
|
if ($self->{RECURSIVE_ITERATOR_FLAG}) { |
if ($self->{RECURSIVE_ITERATOR_FLAG}) { |
# grab the next from the recursive iterator |
# grab the next from the recursive iterator |
Line 2952 sub next {
|
Line 3005 sub next {
|
} |
} |
|
|
# Is this the end of a branch? If so, all of the resources examined above |
# Is this the end of a branch? If so, all of the resources examined above |
# led to lower levels then the one we are currently at, so we push a END_BRANCH |
# led to lower levels than the one we are currently at, so we push a END_BRANCH |
# marker onto the stack so we don't forget. |
# marker onto the stack so we don't forget. |
# Example: For the usual A(BC)(DE)F case, when the iterator goes down the |
# Example: For the usual A(BC)(DE)F case, when the iterator goes down the |
# BC branch and gets to C, it will see F as the only next resource, but it's |
# BC branch and gets to C, it will see F as the only next resource, but it's |
Line 3288 X<symb> X<resource, symb>
|
Line 3341 X<symb> X<resource, symb>
|
All resources also have B<symb>s, which uniquely identify a resource |
All resources also have B<symb>s, which uniquely identify a resource |
in a course. Many internal LON-CAPA functions expect a symb. A symb |
in a course. Many internal LON-CAPA functions expect a symb. A symb |
carries along with it the URL of the resource, and the map it appears |
carries along with it the URL of the resource, and the map it appears |
in. Symbs are much larger then resource IDs. |
in. Symbs are much larger than resource IDs. |
|
|
=cut |
=cut |
|
|
Line 3364 false.
|
Line 3417 false.
|
|
|
=item * B<randompick>: |
=item * B<randompick>: |
|
|
Returns true for a map if the randompick feature is being used on the |
Returns the number of randomly picked items for a map if the randompick |
map. (?) |
feature is being used on the map. |
|
|
|
=item * B<randomorder>: |
|
|
|
Returns true for a map if the randomorder feature is being used on the |
|
map. |
|
|
=item * B<src>: |
=item * B<src>: |
|
|
Line 3395 sub kind { my $self=shift; return $self-
|
Line 3453 sub kind { my $self=shift; return $self-
|
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); } |
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); } |
sub randompick { |
sub randompick { |
my $self = shift; |
my $self = shift; |
return $self->parmval('randompick'); |
my $randompick = $self->parmval('randompick'); |
|
return $randompick; |
|
} |
|
sub randomorder { |
|
my $self = shift; |
|
my $randomorder = $self->parmval('randomorder'); |
|
return ($randomorder =~ /^yes$/i); |
} |
} |
sub link { |
sub link { |
my $self=shift; |
my $self=shift; |
Line 3473 sub compTitle {
|
Line 3537 sub compTitle {
|
} |
} |
return $title; |
return $title; |
} |
} |
|
|
=pod |
=pod |
|
|
B<Predicate Testing the Resource> |
B<Predicate Testing the Resource> |
Line 3515 sub retrieveResources {
|
Line 3580 sub retrieveResources {
|
|
|
sub is_exam { |
sub is_exam { |
my ($self,$part) = @_; |
my ($self,$part) = @_; |
if ($self->parmval('type',$part) eq 'exam') { |
my $type = $self->parmval('type',$part); |
|
if ($type eq 'exam') { |
return 1; |
return 1; |
} |
} |
if ($self->src() =~ /\.(exam)$/) { |
if ($self->src() =~ /\.(exam)$/) { |
Line 3538 sub is_page {
|
Line 3604 sub is_page {
|
sub is_practice { |
sub is_practice { |
my $self=shift; |
my $self=shift; |
my ($part) = @_; |
my ($part) = @_; |
if ($self->parmval('type',$part) eq 'practice') { |
my $type = $self->parmval('type',$part); |
|
if ($type eq 'practice') { |
return 1; |
return 1; |
} |
} |
return 0; |
return 0; |
Line 3551 sub is_problem {
|
Line 3618 sub is_problem {
|
} |
} |
return 0; |
return 0; |
} |
} |
|
sub is_raw_problem { |
|
my $self=shift; |
|
my $src = $self->src(); |
|
if ($src =~ /\.(problem|exam|quiz|assess|survey|form|library|task)$/) { |
|
return 1; |
|
} |
|
return 0; |
|
} |
|
|
sub contains_problem { |
sub contains_problem { |
my $self=shift; |
my $self=shift; |
if ($self->is_page()) { |
if ($self->is_page()) { |
Line 3559 sub contains_problem {
|
Line 3635 sub contains_problem {
|
} |
} |
return 0; |
return 0; |
} |
} |
|
sub map_contains_problem { |
|
my $self=shift; |
|
if ($self->is_map()) { |
|
my $has_problem= |
|
$self->hasResource($self,sub { $_[0]->is_problem() },1); |
|
return $has_problem; |
|
} |
|
return 0; |
|
} |
sub is_sequence { |
sub is_sequence { |
my $self=shift; |
my $self=shift; |
return $self->navHash("is_map_", 1) && |
return $self->navHash("is_map_", 1) && |
Line 3567 sub is_sequence {
|
Line 3652 sub is_sequence {
|
sub is_survey { |
sub is_survey { |
my $self = shift(); |
my $self = shift(); |
my $part = shift(); |
my $part = shift(); |
if ($self->parmval('type',$part) eq 'survey') { |
my $type = $self->parmval('type',$part); |
|
if ($type eq 'survey') { |
return 1; |
return 1; |
} |
} |
if ($self->src() =~ /\.(survey)$/) { |
if ($self->src() =~ /\.(survey)$/) { |
Line 3665 sub map_type {
|
Line 3751 sub map_type {
|
|
|
# These functions will be responsible for returning the CORRECT |
# These functions will be responsible for returning the CORRECT |
# VALUE for the parameter, no matter what. So while they may look |
# VALUE for the parameter, no matter what. So while they may look |
# like direct calls to parmval, they can be more then that. |
# like direct calls to parmval, they can be more than that. |
# So, for instance, the duedate function should use the "duedatetype" |
# So, for instance, the duedate function should use the "duedatetype" |
# information, rather then the resource object user. |
# information, rather than the resource object user. |
|
|
=pod |
=pod |
|
|
Line 3743 Get the weight for the problem.
|
Line 3829 Get the weight for the problem.
|
|
|
sub acc { |
sub acc { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return $self->parmval("acc", $part); |
my $acc = $self->parmval("acc", $part); |
|
return $acc; |
} |
} |
sub answerdate { |
sub answerdate { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
# Handle intervals |
# Handle intervals |
if ($self->parmval("answerdate.type", $part) eq 'date_interval') { |
my $answerdatetype = $self->parmval("answerdate.type", $part); |
return $self->duedate($part) + |
my $answerdate = $self->parmval("answerdate", $part); |
$self->parmval("answerdate", $part); |
my $duedate = $self->parmval("duedate", $part); |
|
if ($answerdatetype eq 'date_interval') { |
|
$answerdate = $duedate + $answerdate; |
} |
} |
return $self->parmval("answerdate", $part); |
return $answerdate; |
} |
} |
sub awarded { |
sub awarded { |
my $self = shift; my $part = shift; |
my $self = shift; my $part = shift; |
Line 3764 sub awarded {
|
Line 3853 sub awarded {
|
sub duedate { |
sub duedate { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
my $date; |
my $date; |
my $interval=$self->parmval("interval", $part); |
my @interval=$self->parmval("interval", $part); |
my $due_date=$self->parmval("duedate", $part); |
my $due_date=$self->parmval("duedate", $part); |
if ($interval =~ /\d+/) { |
if ($interval[0] =~ /\d+/) { |
my $first_access=&Apache::lonnet::get_first_access('map',$self->symb); |
my $first_access=&Apache::lonnet::get_first_access($interval[1], |
|
$self->symb); |
if (defined($first_access)) { |
if (defined($first_access)) { |
$interval = $first_access+$interval; |
my $interval = $first_access+$interval[0]; |
$date = ($interval < $due_date)? $interval : $due_date; |
$date = (!$due_date || $interval < $due_date) ? $interval |
|
: $due_date; |
} else { |
} else { |
$date = $due_date; |
$date = $due_date; |
} |
} |
Line 3781 sub duedate {
|
Line 3872 sub duedate {
|
} |
} |
sub handgrade { |
sub handgrade { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return $self->parmval("handgrade", $part); |
my @response_ids = $self->responseIds($part); |
|
if (@response_ids) { |
|
foreach my $response_id (@response_ids) { |
|
my $handgrade = $self->parmval("handgrade",$part.'_'.$response_id); |
|
if (lc($handgrade) eq 'yes') { |
|
return 'yes'; |
|
} |
|
} |
|
} |
|
my $handgrade = $self->parmval("handgrade", $part); |
|
return $handgrade; |
} |
} |
sub maxtries { |
sub maxtries { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return $self->parmval("maxtries", $part); |
my $maxtries = $self->parmval("maxtries", $part); |
|
return $maxtries; |
} |
} |
sub opendate { |
sub opendate { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
if ($self->parmval("opendate.type", $part) eq 'date_interval') { |
my $opendatetype = $self->parmval("opendate.type", $part); |
return $self->duedate($part) - |
my $opendate = $self->parmval("opendate", $part); |
$self->parmval("opendate", $part); |
if ($opendatetype eq 'date_interval') { |
|
my $duedate = $self->duedate($part); |
|
$opendate = $duedate - $opendate; |
} |
} |
return $self->parmval("opendate"); |
return $opendate; |
} |
} |
sub problemstatus { |
sub problemstatus { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return lc $self->parmval("problemstatus", $part); |
my $problemstatus = $self->parmval("problemstatus", $part); |
|
return lc($problemstatus); |
} |
} |
sub sig { |
sub sig { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return $self->parmval("sig", $part); |
my $sig = $self->parmval("sig", $part); |
|
return $sig; |
} |
} |
sub tol { |
sub tol { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return $self->parmval("tol", $part); |
my $tol = $self->parmval("tol", $part); |
|
return $tol; |
} |
} |
sub tries { |
sub tries { |
my $self = shift; |
my $self = shift; |
my $tries = $self->queryRestoreHash('tries', shift); |
my $tries = $self->queryRestoreHash('tries', shift); |
if (!defined($tries)) { return '0';} |
if (!defined($tries)) { return '0';} |
Line 3815 sub tries {
|
Line 3922 sub tries {
|
} |
} |
sub type { |
sub type { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
return $self->parmval("type", $part); |
my $type = $self->parmval("type", $part); |
|
return $type; |
} |
} |
sub weight { |
sub weight { |
my $self = shift; my $part = shift; |
my $self = shift; my $part = shift; |
if (!defined($part)) { $part = '0'; } |
if (!defined($part)) { $part = '0'; } |
return &Apache::lonnet::EXT('resource.'.$part.'.weight', |
my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', |
$self->symb(), $env{'user.domain'}, |
$self->symb(), $env{'user.domain'}, |
$env{'user.name'}, |
$env{'user.name'}, |
$env{'request.course.sec'}); |
$env{'request.course.sec'}); |
|
return $weight; |
} |
} |
sub part_display { |
sub part_display { |
my $self= shift(); my $partID = shift(); |
my $self= shift(); my $partID = shift(); |
Line 4497 sub status {
|
Line 4606 sub status {
|
#if ($self->{RESOURCE_ERROR}) { return NETWORK_FAILURE; } |
#if ($self->{RESOURCE_ERROR}) { return NETWORK_FAILURE; } |
if ($completionStatus == NETWORK_FAILURE) { return NETWORK_FAILURE; } |
if ($completionStatus == NETWORK_FAILURE) { return NETWORK_FAILURE; } |
|
|
my $suppressFeedback = $self->problemstatus($part) eq 'no'; |
my $suppressFeedback = 0; |
|
if (($self->problemstatus($part) eq 'no') || |
|
($self->problemstatus($part) eq 'no_feedback_ever')) { |
|
$suppressFeedback = 1; |
|
} |
# 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() && |