version 1.285, 2004/08/31 15:28:03
|
version 1.302, 2004/11/02 21:02:01
|
Line 35 use Apache::loncommon();
|
Line 35 use Apache::loncommon();
|
use Apache::lonmenu(); |
use Apache::lonmenu(); |
use Apache::lonlocal; |
use Apache::lonlocal; |
use POSIX qw (floor strftime); |
use POSIX qw (floor strftime); |
use Data::Dumper; # for debugging, not always used |
use Data::Dumper; # for debugging, not always |
|
|
# symbolic constants |
# symbolic constants |
sub SYMB { return 1; } |
sub SYMB { return 1; } |
Line 119 window.status='Done.';
|
Line 119 window.status='Done.';
|
ENDCLOSE |
ENDCLOSE |
} |
} |
|
|
sub nav_control_js { |
|
my $nav=($ENV{'environment.remotenavmap'} eq 'on'); |
|
return (<<NAVCONTROL); |
|
var w_loncapanav_flag="$nav"; |
|
|
|
|
|
function gonav(url) { |
|
if (w_loncapanav_flag != 1) { |
|
go(url); |
|
} else { |
|
navwindow=window.open(url, |
|
"loncapanav","height=600,width=400,scrollbars=1"); |
|
} |
|
} |
|
NAVCONTROL |
|
} |
|
|
|
sub update { |
sub update { |
if ($ENV{'environment.remotenavmap'} ne 'on') { return ''; } |
if ($ENV{'environment.remotenavmap'} ne 'on') { return ''; } |
if (!$ENV{'request.course.id'}) { return ''; } |
if (!$ENV{'request.course.id'}) { return ''; } |
Line 354 ENDSUBM
|
Line 337 ENDSUBM
|
} else { |
} else { |
&add_linkitem(\%toplinkitems,'firsthomework', |
&add_linkitem(\%toplinkitems,'firsthomework', |
'location.href="navmaps?jumpToFirstHomework"', |
'location.href="navmaps?jumpToFirstHomework"', |
"Go To My First Homework Problem"); |
"Show Me My First Homework Problem"); |
} |
} |
|
|
my $suppressEmptySequences = 0; |
my $suppressEmptySequences = 0; |
Line 370 ENDSUBM
|
Line 353 ENDSUBM
|
return $res->completable() || $res->is_map(); |
return $res->completable() || $res->is_map(); |
}; |
}; |
&add_linkitem(\%toplinkitems,'everything', |
&add_linkitem(\%toplinkitems,'everything', |
'location.href="locatnavmaps?sort='.$ENV{'form.sort'}.'"', |
'location.href="navmaps?sort='.$ENV{'form.sort'}.'"', |
"Show Everything"); |
"Show Everything"); |
$r->print("<p><font size='+2'>".&mt("Uncompleted Homework")."</font></p>"); |
$r->print("<p><font size='+2'>".&mt("Uncompleted Homework")."</font></p>"); |
$ENV{'form.filter'} = ''; |
$ENV{'form.filter'} = ''; |
Line 392 ENDSUBM
|
Line 375 ENDSUBM
|
<option value=\"default\" $selected{'default'}>".&mt('Default')."</option> |
<option value=\"default\" $selected{'default'}>".&mt('Default')."</option> |
<option value=\"title\" $selected{'title'} >".&mt('Title')."</option> |
<option value=\"title\" $selected{'title'} >".&mt('Title')."</option> |
<option value=\"duedate\" $selected{'duedate'}>".&mt('Duedate')."</option> |
<option value=\"duedate\" $selected{'duedate'}>".&mt('Duedate')."</option> |
|
<option value=\"discussion\" $selected{'discussion'}>".&mt('Has Discussion')."</option> |
</select> |
</select> |
</nobr> |
</nobr> |
</form>"); |
</form>"); |
Line 409 ENDSUBM
|
Line 393 ENDSUBM
|
'caller' => 'navmapsdisplay', |
'caller' => 'navmapsdisplay', |
'linkitems' => \%toplinkitems}; |
'linkitems' => \%toplinkitems}; |
my $render = render($renderArgs); |
my $render = render($renderArgs); |
$navmap->untieHashes(); |
|
|
|
# If no resources were printed, print a reassuring message so the |
# If no resources were printed, print a reassuring message so the |
# user knows there was no error. |
# user knows there was no error. |
Line 1034 sub render_resource {
|
Line 1017 sub render_resource {
|
|
|
my $partLabel = ""; |
my $partLabel = ""; |
my $newBranchText = ""; |
my $newBranchText = ""; |
|
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); |
# If this is a new branch, label it so |
# If this is a new branch, label it so |
if ($params->{'isNewBranch'}) { |
if ($params->{'isNewBranch'}) { |
$newBranchText = "<img src='/adm/lonIcons/branch.gif' border='0' />"; |
$newBranchText = "<img src='$location/branch.gif' border='0' />"; |
} |
} |
|
|
# links to open and close the folder |
# links to open and close the folder |
Line 1045 sub render_resource {
|
Line 1028 sub render_resource {
|
my $linkclose = "</a>"; |
my $linkclose = "</a>"; |
|
|
# Default icon: unknown page |
# Default icon: unknown page |
my $icon = "<img src='/adm/lonIcons/unknown.gif' alt='' border='0' />"; |
my $icon = "<img src='$location/unknown.gif' alt='' border='0' />"; |
|
|
if ($resource->is_problem()) { |
if ($resource->is_problem()) { |
if ($part eq '0' || $params->{'condensed'}) { |
if ($part eq '0' || $params->{'condensed'}) { |
$icon = '<img src="/adm/lonIcons/problem.gif" alt="" border="0" />'; |
$icon ='<img src="'.$location.'/problem.gif" alt="" border="0" />'; |
} else { |
} else { |
$icon = $params->{'indentString'}; |
$icon = $params->{'indentString'}; |
} |
} |
} else { |
} else { |
$icon = "<img src='".&Apache::loncommon::icon($resource->src). |
$icon = "<img src='".&Apache::loncommon::lonhttpdurl(&Apache::loncommon::icon($resource->src))."' alt='' border='0' />"; |
"' alt='' border='0' />"; |
|
} |
} |
|
|
# Display the correct map icon to open or shut map |
# Display the correct map icon to open or shut map |
Line 1070 sub render_resource {
|
Line 1052 sub render_resource {
|
|
|
if (!$params->{'resource_no_folder_link'}) { |
if (!$params->{'resource_no_folder_link'}) { |
$icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif'; |
$icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif'; |
$icon = "<img src='/adm/lonIcons/$icon' alt='' border='0' />"; |
$icon = "<img src='$location/$icon' alt='' border='0' />"; |
|
|
$linkopen = "<a href='" . $params->{'url'} . '?' . |
$linkopen = "<a href='" . $params->{'url'} . '?' . |
$params->{'queryString'} . '&filter='; |
$params->{'queryString'} . '&filter='; |
Line 1087 sub render_resource {
|
Line 1069 sub render_resource {
|
# Don't allow users to manipulate folder |
# Don't allow users to manipulate folder |
$icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . |
$icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . |
'.nomanip.gif'; |
'.nomanip.gif'; |
$icon = "<img src='/adm/lonIcons/$icon' alt='' border='0' />"; |
$icon = "<img src='$location/$icon' alt='' border='0' />"; |
|
|
$linkopen = ""; |
$linkopen = ""; |
$linkclose = ""; |
$linkclose = ""; |
Line 1155 sub render_communication_status {
|
Line 1137 sub render_communication_status {
|
my $link = $params->{"resourceLink"}; |
my $link = $params->{"resourceLink"}; |
my $linkopen = "<a href='$link'>"; |
my $linkopen = "<a href='$link'>"; |
my $linkclose = "</a>"; |
my $linkclose = "</a>"; |
|
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
if ($resource->hasDiscussion()) { |
if ($resource->hasDiscussion()) { |
$discussionHTML = $linkopen . |
$discussionHTML = $linkopen . |
'<img border="0" src="/adm/lonMisc/chat.gif" />' . |
'<img border="0" src="'.$location.'/chat.gif" />' . |
$linkclose; |
$linkclose; |
} |
} |
|
|
Line 1168 sub render_communication_status {
|
Line 1150 sub render_communication_status {
|
if ($_) { |
if ($_) { |
$feedbackHTML .= ' <a href="/adm/email?display=' |
$feedbackHTML .= ' <a href="/adm/email?display=' |
. &Apache::lonnet::escape($_) . '">' |
. &Apache::lonnet::escape($_) . '">' |
. '<img src="/adm/lonMisc/feedback.gif" ' |
. '<img src="'.$location.'/feedback.gif" ' |
. 'border="0" /></a>'; |
. 'border="0" /></a>'; |
} |
} |
} |
} |
Line 1183 sub render_communication_status {
|
Line 1165 sub render_communication_status {
|
$errorcount++; |
$errorcount++; |
$errorHTML .= ' <a href="/adm/email?display=' |
$errorHTML .= ' <a href="/adm/email?display=' |
. &Apache::lonnet::escape($_) . '">' |
. &Apache::lonnet::escape($_) . '">' |
. '<img src="/adm/lonMisc/bomb.gif" ' |
. '<img src="'.$location.'/bomb.gif" ' |
. 'border="0" /></a>'; |
. 'border="0" /></a>'; |
} |
} |
} |
} |
Line 1212 sub render_quick_status {
|
Line 1194 sub render_quick_status {
|
my $icon = $statusIconMap{$resource->simpleStatus($part)}; |
my $icon = $statusIconMap{$resource->simpleStatus($part)}; |
my $alt = $iconAltTags{$icon}; |
my $alt = $iconAltTags{$icon}; |
if ($icon) { |
if ($icon) { |
$result .= "<td width='30' valign='center' width='50' align='right'>$linkopen<img width='25' height='25' src='/adm/lonIcons/$icon' border='0' alt='$alt' />$linkclose</td>\n"; |
my $location= |
|
&Apache::loncommon::lonhttpdurl("/adm/lonIcons/$icon"); |
|
$result .= "<td width='30' valign='center' width='50' align='right'>$linkopen<img width='25' height='25' src='$location' border='0' alt='$alt' />$linkclose</td>\n"; |
} else { |
} else { |
$result .= "<td width='30'> </td>\n"; |
$result .= "<td width='30'> </td>\n"; |
} |
} |
Line 1343 sub setDefault {
|
Line 1327 sub setDefault {
|
return $val; |
return $val; |
} |
} |
|
|
|
sub cmp_title { |
|
my ($atitle,$btitle) = (lc($_[0]->compTitle),lc($_[1]->compTitle)); |
|
$atitle=~s/^\s*//; |
|
$btitle=~s/^\s*//; |
|
return $atitle cmp $btitle; |
|
} |
|
|
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 = ''; |
my $result = ''; |
|
|
# Configure the renderer. |
# Configure the renderer. |
my $cols = $args->{'cols'}; |
my $cols = $args->{'cols'}; |
if (!defined($cols)) { |
if (!defined($cols)) { |
Line 1428 sub render {
|
Line 1418 sub render {
|
# We only need to do this if we need to open the maps to show the |
# We only need to do this if we need to open the maps to show the |
# current position. This will change the counter so we can't count |
# current position. This will change the counter so we can't count |
# for the jump marker with this loop. |
# for the jump marker with this loop. |
while (($curRes = $mapIterator->next()) && !$found) { |
while ($here && ($curRes = $mapIterator->next()) && !$found) { |
if (ref($curRes) && $curRes->symb() eq $here) { |
if (ref($curRes) && $curRes->symb() eq $here) { |
my $mapStack = $mapIterator->getStack(); |
my $mapStack = $mapIterator->getStack(); |
|
|
Line 1504 sub render {
|
Line 1494 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">'; |
$result .= '<table border="0" cellpadding="2" cellspacing="0">'; |
my $date=localtime; |
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"); |
if ($navmap->{LAST_CHECK}) { |
if ($navmap->{LAST_CHECK}) { |
$result .= |
$result .= |
'<img src="/adm/lonMisc/chat.gif"> '.&mt('New discussion since').' '. |
'<img src="'.$location.'/chat.gif"> '.&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="/adm/lonMisc/feedback.gif"> '.&mt('New message (click to open)').'<p>'. |
'<img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)').'<p>'. |
'</td>'; |
'</td>'; |
} else { |
} else { |
$result .= '<td align="center" valign="bottom"> '. |
$result .= '<td align="center" valign="bottom"> '. |
'<img src="/adm/lonMisc/chat.gif"> '.&mt('Discussions').'</td><td align="center" valign="bottom">'. |
'<img src="'.$location.'/chat.gif"> '.&mt('Discussions').'</td><td align="center" valign="bottom">'. |
' <img src="/adm/lonMisc/feedback.gif"> '.&mt('New message (click to open)'). |
' <img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)'). |
'</td>'; |
'</td>'; |
} |
} |
|
|
Line 1549 sub render {
|
Line 1540 sub render {
|
|
|
# Check for any unread discussions in all resources. |
# Check for any unread discussions in all resources. |
if ($args->{'caller'} eq 'navmapsdisplay') { |
if ($args->{'caller'} eq 'navmapsdisplay') { |
my $totdisc = 0; |
&add_linkitem($args->{'linkitems'},'clearbubbles', |
my $haveDisc = ''; |
'document.clearbubbles.submit()', |
my @allres=$navmap->retrieveResources(); |
'Mark all posts read'); |
foreach my $resource (@allres) { |
my $time=time; |
if ($resource->hasDiscussion()) { |
$result .= (<<END); |
my $ressymb; |
<form name="clearbubbles" method="post" action="/adm/feedback"> |
if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) { |
<input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" /> |
$ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard'; |
<input type="hidden" name="navtime" value="$time" /> |
} else { |
END |
$ressymb = $resource->symb(); |
if ($args->{'sort'} eq 'discussion') { |
|
my $totdisc = 0; |
|
my $haveDisc = ''; |
|
my @allres=$navmap->retrieveResources(); |
|
foreach my $resource (@allres) { |
|
if ($resource->hasDiscussion()) { |
|
my $ressymb; |
|
if ($resource->symb() =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) { |
|
$ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard'; |
|
} else { |
|
$ressymb = $resource->symb(); |
|
} |
|
$haveDisc .= $ressymb.':'; |
|
$totdisc ++; |
} |
} |
$haveDisc .= $ressymb.':'; |
|
$totdisc ++; |
|
} |
} |
} |
if ($totdisc > 0) { |
if ($totdisc > 0) { |
$haveDisc =~ s/:$//; |
$haveDisc =~ s/:$//; |
$result .= (<<END); |
my $navurl = $ENV{'QUERY_STRING'}; |
<input type="hidden" name="navmaps" value="$haveDisc" /> |
&add_linkitem($args->{'linkitems'},'clearbubbles', |
</form> |
'document.clearbubbles.submit()', |
|
'Mark all posts read'); |
|
$result .= (<<END); |
|
<form name="clearbubbles" method="post" action="/adm/feedback"> |
|
<input type="hidden" name="navurl" value="$ENV{'QUERY_STRING'}" /> |
|
<input type="hidden" name="navmaps" value="$haveDisc" /> |
|
</form> |
|
END |
END |
|
} |
} |
} |
|
$result.='</form>'; |
} |
} |
|
|
if ($args->{'caller'} eq 'navmapsdisplay') { |
if ($args->{'caller'} eq 'navmapsdisplay') { |
Line 1624 END
|
Line 1621 END
|
$args->{'indentLevel'} = 0; |
$args->{'indentLevel'} = 0; |
$args->{'isNewBranch'} = 0; |
$args->{'isNewBranch'} = 0; |
$args->{'condensed'} = 0; |
$args->{'condensed'} = 0; |
$args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='/adm/lonIcons/whitespace1.gif' width='25' height='1' alt='' border='0' />"); |
my $location= |
|
&Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace1.gif"); |
|
$args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='$location' width='25' height='1' alt='' border='0' />"); |
$args->{'displayedHereMarker'} = 0; |
$args->{'displayedHereMarker'} = 0; |
|
|
# If we're suppressing empty sequences, look for them here. Use DFS for speed, |
# If we're suppressing empty sequences, look for them here. Use DFS for speed, |
Line 1685 END
|
Line 1684 END
|
return &$oldFilterFunc($res); |
return &$oldFilterFunc($res); |
}; |
}; |
@resources=$navmap->retrieveResources(undef,$filterFunc); |
@resources=$navmap->retrieveResources(undef,$filterFunc); |
@resources= sort {lc($a->compTitle) cmp lc($b->compTitle)} @resources; |
@resources= sort { &cmp_title($a,$b) } @resources; |
} elsif ($args->{'sort'} eq 'duedate') { |
} elsif ($args->{'sort'} eq 'duedate') { |
@resources=$navmap->retrieveResources(undef, |
my $oldFilterFunc = $filterFunc; |
sub { shift->is_problem(); }); |
my $filterFunc= |
@resources= sort |
sub { |
{ |
my ($res)=@_; |
|
if (!$res->is_problem()) { return 0;} |
|
return &$oldFilterFunc($res); |
|
}; |
|
@resources=$navmap->retrieveResources(undef,$filterFunc); |
|
@resources= sort { |
if ($a->duedate ne $b->duedate) { |
if ($a->duedate ne $b->duedate) { |
return $a->duedate cmp $b->duedate; |
return $a->duedate cmp $b->duedate; |
} else { |
|
lc($a->compTitle) cmp lc($b->compTitle) |
|
} |
} |
|
my $value=&cmp_title($a,$b); |
|
return $value; |
} @resources; |
} @resources; |
|
} elsif ($args->{'sort'} eq 'discussion') { |
|
my $oldFilterFunc = $filterFunc; |
|
my $filterFunc= |
|
sub { |
|
my ($res)=@_; |
|
if (!$res->hasDiscussion() && |
|
!$res->getFeedback() && |
|
!$res->getErrors()) { return 0;} |
|
return &$oldFilterFunc($res); |
|
}; |
|
@resources=$navmap->retrieveResources(undef,$filterFunc); |
|
@resources= sort { &cmp_title($a,$b) } @resources; |
} else { |
} else { |
#unknow sort mechanism or default |
#unknow sort mechanism or default |
undef($args->{'sort'}); |
undef($args->{'sort'}); |
Line 1906 if (location.href.indexOf('#curloc')==-1
|
Line 1922 if (location.href.indexOf('#curloc')==-1
|
$r->rflush(); |
$r->rflush(); |
} |
} |
|
|
if ($mustCloseNavMap) { $navmap->untieHashes(); } |
|
|
|
return $result; |
return $result; |
} |
} |
|
|
Line 1947 ENDBLOCK
|
Line 1961 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"; |
</nobr></form></td>'."\n"; |
|
|
return $result; |
return $result; |
} |
} |
|
|
Line 2007 successful, or B<undef> if not.
|
Line 2022 successful, or B<undef> if not.
|
|
|
=back |
=back |
|
|
When you are done with the $navmap object, you I<must> call |
|
$navmap->untieHashes(), or you'll prevent the current user from using that |
|
course until the web server is restarted. (!) |
|
|
|
=head2 Methods |
=head2 Methods |
|
|
=over 4 |
=over 4 |
Line 2156 sub generate_email_discuss_status {
|
Line 2167 sub generate_email_discuss_status {
|
|
|
foreach my $msgid (split(/\&/, $keys)) { |
foreach my $msgid (split(/\&/, $keys)) { |
$msgid=&Apache::lonnet::unescape($msgid); |
$msgid=&Apache::lonnet::unescape($msgid); |
my $plain=&Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid)); |
if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) { |
if ($plain=~/(Error|Feedback) \[([^\]]+)\]/) { |
my $plain= |
my ($what,$url)=($1,$2); |
&Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid)); |
my %status= |
if ($plain=~/(Error|Feedback) \[([^\]]+)\]/) { |
&Apache::lonnet::get('email_status',[$msgid]); |
my ($what,$url)=($1,$2); |
if ($status{$msgid}=~/^error\:/) { |
|
$status{$msgid}=''; |
|
} |
|
|
|
if (($status{$msgid} eq 'new') || |
|
(!$status{$msgid})) { |
|
if ($what eq 'Error') { |
if ($what eq 'Error') { |
$error{$url}.=','.$msgid; |
$error{$url}.=','.$msgid; |
} else { |
} else { |
Line 2176 sub generate_email_discuss_status {
|
Line 2181 sub generate_email_discuss_status {
|
} |
} |
} |
} |
|
|
|
#url's of resources that have feedbacks |
$self->{FEEDBACK} = \%feedback; |
$self->{FEEDBACK} = \%feedback; |
$self->{ERROR_MSG} = \%error; # what is this? JB |
#or errors |
|
$self->{ERROR_MSG} = \%error; |
$self->{DISCUSSION_TIME} = \%discussiontime; |
$self->{DISCUSSION_TIME} = \%discussiontime; |
$self->{EMAIL_STATUS} = \%emailstatus; |
$self->{EMAIL_STATUS} = \%emailstatus; |
$self->{LAST_READ} = \%lastreadtime; |
$self->{LAST_READ} = \%lastreadtime; |
Line 2231 sub getIterator {
|
Line 2238 sub getIterator {
|
return $iterator; |
return $iterator; |
} |
} |
|
|
# unties the hash when done |
|
sub untieHashes { |
|
my $self = shift; |
|
untie %{$self->{NAV_HASH}}; |
|
untie %{$self->{PARM_HASH}}; |
|
} |
|
|
|
# Private method: Does the given resource (as a symb string) have |
# Private method: Does the given resource (as a symb string) have |
# current discussion? Returns 0 if chat/mail data not extracted. |
# current discussion? Returns 0 if chat/mail data not extracted. |
sub hasDiscussion { |
sub hasDiscussion { |
Line 2618 sub hasResource {
|
Line 2618 sub hasResource {
|
1; |
1; |
|
|
package Apache::lonnavmaps::iterator; |
package Apache::lonnavmaps::iterator; |
|
use WeakRef; |
=pod |
=pod |
|
|
=back |
=back |
Line 2758 sub new {
|
Line 2758 sub new {
|
my $class = ref($proto) || $proto; |
my $class = ref($proto) || $proto; |
my $self = {}; |
my $self = {}; |
|
|
$self->{NAV_MAP} = shift; |
weaken($self->{NAV_MAP} = shift); |
return undef unless ($self->{NAV_MAP}); |
return undef unless ($self->{NAV_MAP}); |
|
|
# Handle the parameters |
# Handle the parameters |
Line 3094 sub populateStack {
|
Line 3094 sub populateStack {
|
1; |
1; |
|
|
package Apache::lonnavmaps::DFSiterator; |
package Apache::lonnavmaps::DFSiterator; |
|
use WeakRef; |
# Not documented in the perldoc: This is a simple iterator that just walks |
# Not documented in the perldoc: This is a simple iterator that just walks |
# through the nav map and presents the resources in a depth-first search |
# through the nav map and presents the resources in a depth-first search |
# fashion, ignorant of conditionals, randomized resources, etc. It presents |
# fashion, ignorant of conditionals, randomized resources, etc. It presents |
Line 3122 sub new {
|
Line 3122 sub new {
|
my $class = ref($proto) || $proto; |
my $class = ref($proto) || $proto; |
my $self = {}; |
my $self = {}; |
|
|
$self->{NAV_MAP} = shift; |
weaken($self->{NAV_MAP} = shift); |
return undef unless ($self->{NAV_MAP}); |
return undef unless ($self->{NAV_MAP}); |
|
|
$self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource(); |
$self->{FIRST_RESOURCE} = shift || $self->{NAV_MAP}->firstResource(); |
Line 3276 sub populateStack {
|
Line 3276 sub populateStack {
|
1; |
1; |
|
|
package Apache::lonnavmaps::resource; |
package Apache::lonnavmaps::resource; |
|
use WeakRef; |
use Apache::lonnet; |
use Apache::lonnet; |
|
|
=pod |
=pod |
Line 3358 sub new {
|
Line 3358 sub new {
|
my $class = ref($proto) || $proto; |
my $class = ref($proto) || $proto; |
my $self = {}; |
my $self = {}; |
|
|
$self->{NAV_MAP} = shift; |
weaken($self->{NAV_MAP} = shift); |
$self->{ID} = shift; |
$self->{ID} = shift; |
|
|
# Store this new resource in the parent nav map's cache. |
# Store this new resource in the parent nav map's cache. |
Line 3479 sub title {
|
Line 3479 sub title {
|
return $self->navHash("title_", 1); } |
return $self->navHash("title_", 1); } |
# considered private and undocumented |
# considered private and undocumented |
sub to { my $self=shift; return $self->navHash("to_", 1); } |
sub to { my $self=shift; return $self->navHash("to_", 1); } |
|
sub condition { |
|
my $self=shift; |
|
my $undercond=$self->navHash("undercond_", 1); |
|
if (!defined($undercond)) { return 1; }; |
|
my $condid=$self->navHash("condid_$undercond"); |
|
if (!defined($condid)) { return 1; }; |
|
my $condition=&Apache::lonnet::directcondval($condid); |
|
return $condition; |
|
} |
|
|
sub compTitle { |
sub compTitle { |
my $self = shift; |
my $self = shift; |
my $title = $self->title(); |
my $title = $self->title(); |
Line 3900 Returns the number of parts of the probl
|
Line 3910 Returns the number of parts of the probl
|
for single part problems, returns 1. For multipart, it returns the |
for single part problems, returns 1. For multipart, it returns the |
number of parts in the problem, not including psuedo-part 0. |
number of parts in the problem, not including psuedo-part 0. |
|
|
|
=item * B<countResponses>(): |
|
|
|
Returns the total number of responses in the problem a student can answer. |
|
|
|
=item * B<responseTypes>(): |
|
|
|
Returns a hash whose keys are the response types. The values are the number |
|
of times each response type is used. This is for the I<entire> problem, not |
|
just a single part. |
|
|
=item * B<multipart>(): |
=item * B<multipart>(): |
|
|
Returns true if the problem is multipart, false otherwise. Use this instead |
Returns true if the problem is multipart, false otherwise. Use this instead |
Line 3946 sub countParts {
|
Line 3966 sub countParts {
|
return scalar(@{$parts}); # + $delta; |
return scalar(@{$parts}); # + $delta; |
} |
} |
|
|
|
sub countResponses { |
|
my $self = shift; |
|
my $count; |
|
foreach my $part (@{$self->parts()}) { |
|
$count+= scalar($self->responseIds($part)); |
|
} |
|
return $count; |
|
} |
|
|
|
sub responseTypes { |
|
my $self = shift; |
|
my %responses; |
|
foreach my $part ($self->parts()) { |
|
foreach my $responsetype ($self->responseType($part)) { |
|
$responses{$responsetype}++ if (defined($responsetype)); |
|
} |
|
} |
|
return %responses; |
|
} |
|
|
sub multipart { |
sub multipart { |
my $self = shift; |
my $self = shift; |
return $self->countParts() > 1; |
return $self->countParts() > 1; |
Line 4049 sub extractParts {
|
Line 4089 sub extractParts {
|
# So we have to use our knowlege of part names to figure out |
# So we have to use our knowlege of part names to figure out |
# where the part names begin and end, and even then, it is possible |
# where the part names begin and end, and even then, it is possible |
# to construct ambiguous situations. |
# to construct ambiguous situations. |
# |
|
my %response_type_by_id; |
|
foreach (split /,/, $metadata) { |
foreach (split /,/, $metadata) { |
if ($_ =~ /^([a-zA-Z]+)response_(.*)/) { |
if ($_ =~ /^([a-zA-Z]+)response_(.*)/) { |
my $responseType = $1; |
my $responseType = $1; |
Line 4066 sub extractParts {
|
Line 4104 sub extractParts {
|
my $responseId = join('_', @otherChunks); |
my $responseId = join('_', @otherChunks); |
push @{$responseIdHash{$partIdSoFar}}, $responseId; |
push @{$responseIdHash{$partIdSoFar}}, $responseId; |
push @{$responseTypeHash{$partIdSoFar}}, $responseType; |
push @{$responseTypeHash{$partIdSoFar}}, $responseType; |
$response_type_by_id{$responseId} = $responseType; |
|
} |
} |
} |
} |
} |
} |
Line 4077 sub extractParts {
|
Line 4114 sub extractParts {
|
if ($resorder) { |
if ($resorder) { |
my @resorder=split(/,/,$resorder); |
my @resorder=split(/,/,$resorder); |
foreach my $part (keys(%responseIdHash)) { |
foreach my $part (keys(%responseIdHash)) { |
my %resids = map { ($_,1) } @{ $responseIdHash{$part} }; |
my $i=0; |
|
my %resids = map { ($_,$i++) } @{ $responseIdHash{$part} }; |
my @neworder; |
my @neworder; |
foreach my $possibleid (@resorder) { |
foreach my $possibleid (@resorder) { |
if (exists($resids{$possibleid})) { |
if (exists($resids{$possibleid})) { |
push(@neworder,$possibleid); |
push(@neworder,$resids{$possibleid}); |
} |
} |
} |
} |
$responseIdHash{$part}=\@neworder; |
my @ids; |
|
my @type; |
|
foreach my $element (@neworder) { |
|
push (@ids,$responseIdHash{$part}->[$element]); |
|
push (@type,$responseTypeHash{$part}->[$element]); |
|
} |
|
$responseIdHash{$part}=\@ids; |
|
$responseTypeHash{$part}=\@type; |
} |
} |
} |
} |
# |
|
# Reorder the response types |
|
foreach my $partid (keys(%responseIdHash)) { |
|
delete($responseTypeHash{$partid}); |
|
foreach my $respid (@{$responseIdHash{$partid}}) { |
|
push(@{$responseTypeHash{$partid}}, |
|
$response_type_by_id{$respid}); |
|
} |
|
} |
|
$self->{RESPONSE_IDS} = \%responseIdHash; |
$self->{RESPONSE_IDS} = \%responseIdHash; |
$self->{RESPONSE_TYPES} = \%responseTypeHash; |
$self->{RESPONSE_TYPES} = \%responseTypeHash; |
} |
} |
Line 4289 sub getCompletionStatus {
|
Line 4325 sub getCompletionStatus {
|
|
|
# Left as separate if statements in case we ever do more with this |
# Left as separate if statements in case we ever do more with this |
if ($status eq 'correct_by_student') {return $self->CORRECT;} |
if ($status eq 'correct_by_student') {return $self->CORRECT;} |
|
if ($status eq 'correct_by_scantron') {return $self->CORRECT;} |
if ($status eq 'correct_by_override') {return $self->CORRECT_BY_OVERRIDE; } |
if ($status eq 'correct_by_override') {return $self->CORRECT_BY_OVERRIDE; } |
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; } |
Line 4625 sub getNext {
|
Line 4662 sub getNext {
|
my $to = $self->to(); |
my $to = $self->to(); |
foreach my $branch ( split(/,/, $to) ) { |
foreach my $branch ( split(/,/, $to) ) { |
my $choice = $self->{NAV_MAP}->getById($branch); |
my $choice = $self->{NAV_MAP}->getById($branch); |
|
if (!$choice->condition()) { next; } |
my $next = $choice->goesto(); |
my $next = $choice->goesto(); |
$next = $self->{NAV_MAP}->getById($next); |
$next = $self->{NAV_MAP}->getById($next); |
|
|