version 1.376, 2006/04/10 21:40:08
|
version 1.390, 2006/07/25 00:57:51
|
Line 40 use Apache::lonnet;
|
Line 40 use Apache::lonnet;
|
use POSIX qw (floor strftime); |
use POSIX qw (floor strftime); |
use Data::Dumper; # for debugging, not always |
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; |
|
|
# symbolic constants |
# symbolic constants |
sub SYMB { return 1; } |
sub SYMB { return 1; } |
Line 258 MENU
|
Line 260 MENU
|
} |
} |
|
|
# Header |
# Header |
$r->print(&Apache::loncommon::start_page('Navigate Course Contents',$js, |
my $course_type = &Apache::loncommon::course_type(); |
|
$r->print(&Apache::loncommon::start_page('Navigate '.$course_type. |
|
' Contents', |
|
$js, |
{'only_body' => $body_only, |
{'only_body' => $body_only, |
'force_register' => |
'force_register' => |
$env{'form.register'},})); |
$env{'form.register'},})); |
Line 268 MENU
|
Line 273 MENU
|
|
|
# Check that it's defined |
# Check that it's defined |
if (!($navmap->courseMapDefined())) { |
if (!($navmap->courseMapDefined())) { |
$r->print(&Apache::loncommon::help_open_menu('','Navigation Screen','Navigation_Screen','',undef,'RAT')); |
$r->print(&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT')); |
$r->print('<font size="+2" color="red">'.&mt('Coursemap undefined.'). |
$r->print('<span class="LC_error">'.&mt('Coursemap undefined.'). |
'</font>' . |
'</span>' . |
&Apache::loncommon::end_page()); |
&Apache::loncommon::end_page()); |
return OK; |
return OK; |
} |
} |
Line 318 MENU
|
Line 323 MENU
|
"Close navigation window"); |
"Close navigation window"); |
} |
} |
|
|
my $jumpToFirstHomework = 0; |
|
# Check to see if the student is jumping to next open, do-able problem |
# Check to see if the student is jumping to next open, do-able problem |
if ($ENV{QUERY_STRING} =~ /^jumpToFirstHomework/) { |
if ($ENV{QUERY_STRING} =~ /^jumpToFirstHomework/) { |
$jumpToFirstHomework = 1; |
|
# Find the next homework problem that they can do. |
# Find the next homework problem that they can do. |
my $iterator = $navmap->getIterator(undef, undef, undef, 1); |
my $iterator = $navmap->getIterator(undef, undef, undef, 1); |
my $curRes; |
my $curRes; |
my $foundDoableProblem = 0; |
my $foundDoableProblem = 0; |
my $problemRes; |
my $minimumduedate; |
|
|
while (($curRes = $iterator->next()) && !$foundDoableProblem) { |
while ($curRes = $iterator->next()) { |
if (ref($curRes) && $curRes->is_problem()) { |
if (ref($curRes) && $curRes->is_problem()) { |
my $status = $curRes->status(); |
my $status = $curRes->status(); |
if ($curRes->completable()) { |
if ($curRes->completable()) { |
$problemRes = $curRes; |
my $thisduedate=$curRes->duedate(); |
|
unless ($foundDoableProblem) { |
|
$minimumduedate=$thisduedate; |
|
} |
|
|
$foundDoableProblem = 1; |
$foundDoableProblem = 1; |
|
|
# Pop open all previous maps |
if ($thisduedate<=$minimumduedate) { |
my $stack = $iterator->getStack(); |
# Pop open all previous maps |
pop @$stack; # last resource in the stack is the problem |
my $stack = $iterator->getStack(); |
# itself, which we don't need in the map stack |
pop @$stack; # last resource in the stack is the problem |
my @mapPcs = map {$_->map_pc()} @$stack; |
# itself, which we don't need in the map stack |
$env{'form.filter'} = join(',', @mapPcs); |
my @mapPcs = map {$_->map_pc()} @$stack; |
|
$env{'form.filter'} = join(',', @mapPcs); |
# Mark as both "here" and "jump" |
|
$env{'form.postsymb'} = $curRes->symb(); |
# Mark as both "here" and "jump" |
|
$env{'form.postsymb'} = $curRes->symb(); |
|
$minimumduedate=$thisduedate; |
|
} |
} |
} |
} |
} |
} |
} |
Line 355 MENU
|
Line 366 MENU
|
} else { |
} else { |
&add_linkitem(\%toplinkitems,'firsthomework', |
&add_linkitem(\%toplinkitems,'firsthomework', |
'location.href="navmaps?jumpToFirstHomework"', |
'location.href="navmaps?jumpToFirstHomework"', |
"Show Me My First Homework Problem"); |
"Show my first due problem"); |
} |
} |
|
|
my $suppressEmptySequences = 0; |
my $suppressEmptySequences = 0; |
Line 372 MENU
|
Line 383 MENU
|
}; |
}; |
&add_linkitem(\%toplinkitems,'everything', |
&add_linkitem(\%toplinkitems,'everything', |
'location.href="navmaps?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 Problems")."</font></p>"); |
$env{'form.filter'} = ''; |
$env{'form.filter'} = ''; |
$env{'form.condition'} = 1; |
$env{'form.condition'} = 1; |
$resource_no_folder_link = 1; |
$resource_no_folder_link = 1; |
Line 381 MENU
|
Line 392 MENU
|
&add_linkitem(\%toplinkitems,'uncompleted', |
&add_linkitem(\%toplinkitems,'uncompleted', |
'location.href="navmaps?sort='.$env{'form.sort'}. |
'location.href="navmaps?sort='.$env{'form.sort'}. |
'&showOnlyHomework=1"', |
'&showOnlyHomework=1"', |
"Show Only Uncompleted Homework"); |
"Show only uncompleted problems"); |
} |
} |
|
|
my %selected=($env{'form.sort'} => 'selected=on'); |
my %selected=($env{'form.sort'} => 'selected=on'); |
Line 463 sub getLinkForResource {
|
Line 474 sub getLinkForResource {
|
my $anchor; |
my $anchor; |
if ($res->is_page()) { |
if ($res->is_page()) { |
foreach (@$stack) { if (defined($_)) { $anchor = $_; } } |
foreach (@$stack) { if (defined($_)) { $anchor = $_; } } |
$anchor=&Apache::lonnet::escape($anchor->shown_symb()); |
$anchor=&escape($anchor->shown_symb()); |
return ($res->link(),$res->shown_symb(),$anchor); |
return ($res->link(),$res->shown_symb(),$anchor); |
} |
} |
# in case folder was skipped over as "only sequence" |
# in case folder was skipped over as "only sequence" |
my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb()); |
my ($map,$id,$src)=&Apache::lonnet::decode_symb($res->symb()); |
if ($map=~/\.page$/) { |
if ($map=~/\.page$/) { |
my $url=&Apache::lonnet::clutter($map); |
my $url=&Apache::lonnet::clutter($map); |
$anchor=&Apache::lonnet::escape($src->shown_symb()); |
$anchor=&escape($src->shown_symb()); |
return ($url,$res->shown_symb(),$anchor); |
return ($url,$res->shown_symb(),$anchor); |
} |
} |
} |
} |
Line 673 sub timeToHumanString {
|
Line 684 sub timeToHumanString {
|
|
|
if($format ne '') { |
if($format ne '') { |
my $timeStr = strftime($format, localtime($time)); |
my $timeStr = strftime($format, localtime($time)); |
return $timeStr.&Apache::lonlocal::gettimezone(); |
return $timeStr.&Apache::lonlocal::gettimezone($time); |
} |
} |
|
|
# Less then 5 days away, display day of the week and |
# Less then 5 days away, display day of the week and |
Line 684 sub timeToHumanString {
|
Line 695 sub timeToHumanString {
|
$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(); |
$timeStr.&Apache::lonlocal::gettimezone($time); |
} |
} |
|
|
my $conjunction='on'; |
my $conjunction='on'; |
Line 699 sub timeToHumanString {
|
Line 710 sub timeToHumanString {
|
my $timeStr = strftime("$conjunction %A, %b %e at %I:%M %P", localtime($time)); |
my $timeStr = strftime("$conjunction %A, %b %e at %I:%M %P", localtime($time)); |
$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(); |
return $timeStr.&Apache::lonlocal::gettimezone($time); |
} |
} |
|
|
# 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 = strftime("$conjunction %A, %b %e %Y at %I:%M %P", localtime($time)); |
$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(); |
return $timeStr.&Apache::lonlocal::gettimezone($time); |
} |
} |
} |
} |
|
|
Line 1085 sub render_resource {
|
Line 1096 sub render_resource {
|
|
|
if ($resource->is_problem()) { |
if ($resource->is_problem()) { |
if ($part eq '0' || $params->{'condensed'}) { |
if ($part eq '0' || $params->{'condensed'}) { |
$icon ='<img src="'.$location.'/problem.gif" alt="'.&mt('Problem').'" border="0" />'; |
$icon = '<img src="'.$location.'/'; |
|
if ($resource->is_task()) { |
|
$icon .= 'task.gif" alt="'.&mt('Task'); |
|
} else { |
|
$icon .= 'problem.gif" alt="'.&mt('Problem'); |
|
} |
|
$icon .='" border="0" />'; |
} else { |
} else { |
$icon = $params->{'indentString'}; |
$icon = $params->{'indentString'}; |
} |
} |
Line 1116 sub render_resource {
|
Line 1133 sub render_resource {
|
removeFromFilter($filter, $mapId); |
removeFromFilter($filter, $mapId); |
$linkopen .= "&condition=" . $it->{CONDITION} . '&hereType=' |
$linkopen .= "&condition=" . $it->{CONDITION} . '&hereType=' |
. $params->{'hereType'} . '&here=' . |
. $params->{'hereType'} . '&here=' . |
&Apache::lonnet::escape($params->{'here'}) . |
&escape($params->{'here'}) . |
'&jump=' . |
'&jump=' . |
&Apache::lonnet::escape($resource->symb()) . |
&escape($resource->symb()) . |
"&folderManip=1\">"; |
"&folderManip=1\">"; |
|
|
} else { |
} else { |
Line 1170 sub render_resource {
|
Line 1187 sub render_resource {
|
!$params->{'condensed'}) { |
!$params->{'condensed'}) { |
my $displaypart=$resource->part_display($part); |
my $displaypart=$resource->part_display($part); |
$partLabel = " (".&mt('Part: [_1]', $displaypart).")"; |
$partLabel = " (".&mt('Part: [_1]', $displaypart).")"; |
if ($link!~/\#/) { $link.='#'.&Apache::lonnet::escape($part); } |
if ($link!~/\#/) { $link.='#'.&escape($part); } |
$title = ""; |
$title = ""; |
} |
} |
|
|
Line 1214 sub render_communication_status {
|
Line 1231 sub render_communication_status {
|
foreach (split(/\,/, $feedback)) { |
foreach (split(/\,/, $feedback)) { |
if ($_) { |
if ($_) { |
$feedbackHTML .= ' <a '.$target.' href="/adm/email?display=' |
$feedbackHTML .= ' <a '.$target.' href="/adm/email?display=' |
. &Apache::lonnet::escape($_) . '">' |
. &escape($_) . '">' |
. '<img src="'.$location.'/feedback.gif" ' |
. '<img src="'.$location.'/feedback.gif" ' |
. 'border="0" /></a>'; |
. 'border="0" /></a>'; |
} |
} |
Line 1229 sub render_communication_status {
|
Line 1246 sub render_communication_status {
|
if ($_) { |
if ($_) { |
$errorcount++; |
$errorcount++; |
$errorHTML .= ' <a '.$target.' href="/adm/email?display=' |
$errorHTML .= ' <a '.$target.' href="/adm/email?display=' |
. &Apache::lonnet::escape($_) . '">' |
. &escape($_) . '">' |
. '<img src="'.$location.'/bomb.gif" ' |
. '<img src="'.$location.'/bomb.gif" ' |
. 'border="0" /></a>'; |
. 'border="0" /></a>'; |
} |
} |
Line 1463 sub render {
|
Line 1480 sub render {
|
$navmap = Apache::lonnavmaps::navmap->new(); |
$navmap = Apache::lonnavmaps::navmap->new(); |
if (!defined($navmap)) { |
if (!defined($navmap)) { |
# no londer in course |
# no londer in course |
return '<font color="red">'.&mt('No course selected').'</font><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 1602 sub render {
|
Line 1619 sub render {
|
my ($link,$text); |
my ($link,$text); |
if ($condition) { |
if ($condition) { |
$link='"navmaps?condition=0&filter=&'.$queryString. |
$link='"navmaps?condition=0&filter=&'.$queryString. |
'&here='.&Apache::lonnet::escape($here).'"'; |
'&here='.&escape($here).'"'; |
$text='Close All Folders'; |
$text='Close all folders'; |
} else { |
} else { |
$link='"navmaps?condition=1&filter=&'.$queryString. |
$link='"navmaps?condition=1&filter=&'.$queryString. |
'&here='.&Apache::lonnet::escape($here).'"'; |
'&here='.&escape($here).'"'; |
$text='Open All Folders'; |
$text='Open all folders'; |
} |
} |
if ($args->{'caller'} eq 'navmapsdisplay') { |
if ($args->{'caller'} eq 'navmapsdisplay') { |
&add_linkitem($args->{'linkitems'},'changefolder', |
&add_linkitem($args->{'linkitems'},'changefolder', |
Line 1652 END
|
Line 1669 END
|
|
|
if ($args->{'caller'} eq 'navmapsdisplay') { |
if ($args->{'caller'} eq 'navmapsdisplay') { |
$result .= '<table><tr><td>'. |
$result .= '<table><tr><td>'. |
&Apache::loncommon::help_open_menu('','Navigation Screen','Navigation_Screen','',undef,'RAT').'</td>'; |
&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT').'</td>'; |
if ($env{'environment.remotenavmap'} ne 'on') { |
if ($env{'environment.remotenavmap'} ne 'on') { |
$result .= '<td> </td>'; |
$result .= '<td> </td>'; |
} else { |
} else { |
Line 1917 END
|
Line 1934 END
|
my $srcHasQuestion = $src =~ /\?/; |
my $srcHasQuestion = $src =~ /\?/; |
$args->{"resourceLink"} = $src. |
$args->{"resourceLink"} = $src. |
($srcHasQuestion?'&':'?') . |
($srcHasQuestion?'&':'?') . |
'symb=' . &Apache::lonnet::escape($symb).$anchor; |
'symb=' . &escape($symb).$anchor; |
} |
} |
# Now, we've decided what parts to show. Loop through them and |
# Now, we've decided what parts to show. Loop through them and |
# show them. |
# show them. |
Line 2222 sub generate_email_discuss_status {
|
Line 2239 sub generate_email_discuss_status {
|
foreach my $msgid (@keys) { |
foreach my $msgid (@keys) { |
if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) { |
if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) { |
my $plain= |
my $plain= |
&Apache::lonnet::unescape(&Apache::lonnet::unescape($msgid)); |
&LONCAPA::unescape(&LONCAPA::unescape($msgid)); |
if ($plain=~/ \[([^\]]+)\]\:/) { |
if ($plain=~/ \[([^\]]+)\]\:/) { |
my $url=$1; |
my $url=$1; |
if ($plain=~/\:Error \[/) { |
if ($plain=~/\:Error \[/) { |
Line 2568 sub parmval_real {
|
Line 2585 sub parmval_real {
|
my $result=''; |
my $result=''; |
|
|
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
|
$mapname = &Apache::lonnet::deversion($mapname); |
# ----------------------------------------------------- Cascading lookup scheme |
# ----------------------------------------------------- Cascading lookup scheme |
my $rwhat=$what; |
my $rwhat=$what; |
$what=~s/^parameter\_//; |
$what=~s/^parameter\_//; |
Line 3824 sub contains_problem {
|
Line 3841 sub contains_problem {
|
} |
} |
sub is_sequence { |
sub is_sequence { |
my $self=shift; |
my $self=shift; |
my $src = $self->src(); |
|
return $self->navHash("is_map_", 1) && |
return $self->navHash("is_map_", 1) && |
$self->navHash("map_type_" . $self->map_pc()) eq 'sequence'; |
$self->navHash("map_type_" . $self->map_pc()) eq 'sequence'; |
} |
} |
Line 3899 Returns a string with the type of the ma
|
Line 3915 Returns a string with the type of the ma
|
sub map_finish { |
sub map_finish { |
my $self = shift; |
my $self = shift; |
my $src = $self->src(); |
my $src = $self->src(); |
$src = Apache::lonnet::clutter($src); |
$src = &Apache::lonnet::clutter($src); |
my $res = $self->navHash("map_finish_$src", 0); |
my $res = $self->navHash("map_finish_$src", 0); |
$res = $self->{NAV_MAP}->getById($res); |
$res = $self->{NAV_MAP}->getById($res); |
return $res; |
return $res; |
Line 3912 sub map_pc {
|
Line 3928 sub map_pc {
|
sub map_start { |
sub map_start { |
my $self = shift; |
my $self = shift; |
my $src = $self->src(); |
my $src = $self->src(); |
$src = Apache::lonnet::clutter($src); |
$src = &Apache::lonnet::clutter($src); |
my $res = $self->navHash("map_start_$src", 0); |
my $res = $self->navHash("map_start_$src", 0); |
$res = $self->{NAV_MAP}->getById($res); |
$res = $self->{NAV_MAP}->getById($res); |
return $res; |
return $res; |
Line 4024 sub awarded {
|
Line 4040 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'}; |
} |
} |
|
# this should work exactly like the copy in lonhomework.pm |
sub duedate { |
sub duedate { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
|
my $date; |
my $interval=$self->parmval("interval", $part); |
my $interval=$self->parmval("interval", $part); |
if ($interval) { |
my $due_date=$self->parmval("duedate", $part); |
|
if ($interval =~ /\d+/) { |
my $first_access=&Apache::lonnet::get_first_access('map',$self->symb); |
my $first_access=&Apache::lonnet::get_first_access('map',$self->symb); |
if ($first_access) { return ($first_access+$interval); } |
if (defined($first_access)) { |
|
$interval = $first_access+$interval; |
|
$date = ($interval < $due_date)? $interval : $due_date; |
|
} else { |
|
$date = $due_date; |
|
} |
|
} else { |
|
$date = $due_date; |
} |
} |
return $self->parmval("duedate", $part); |
return $date; |
} |
} |
sub handgrade { |
sub handgrade { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
Line 4149 email data was not extracted when the na
|
Line 4175 email data was not extracted when the na
|
used like this: |
used like this: |
|
|
for (split(/\,/, $res->getFeedback())) { |
for (split(/\,/, $res->getFeedback())) { |
my $link = &Apache::lonnet::escape($_); |
my $link = &escape($_); |
... |
... |
|
|
and use the link as appropriate. |
and use the link as appropriate. |
Line 4379 sub extractParts {
|
Line 4405 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. |
foreach (split /,/, $metadata) { |
foreach my $data (split /,/, $metadata) { |
if ($_ =~ /^([a-zA-Z]+)response_(.*)/ |
if ($data =~ /^([a-zA-Z]+)response_(.*)/ |
|| $_ =~ /^(Task)_(.*)/) { |
|| $data =~ /^(Task)_(.*)/) { |
my $responseType = $1; |
my $responseType = $1; |
my $partStuff = $2; |
my $partStuff = $2; |
my $partIdSoFar = ''; |
my $partIdSoFar = ''; |
Line 4393 sub extractParts {
|
Line 4419 sub extractParts {
|
if ($parts{$partIdSoFar}) { |
if ($parts{$partIdSoFar}) { |
my @otherChunks = @partChunks[$i+1..$#partChunks]; |
my @otherChunks = @partChunks[$i+1..$#partChunks]; |
my $responseId = join('_', @otherChunks); |
my $responseId = join('_', @otherChunks); |
push @{$responseIdHash{$partIdSoFar}}, $responseId; |
if ($self->is_task()) { |
push @{$responseTypeHash{$partIdSoFar}}, $responseType; |
push(@{$responseIdHash{$partIdSoFar}}, |
|
$partIdSoFar); |
|
} else { |
|
push(@{$responseIdHash{$partIdSoFar}}, |
|
$responseId); |
|
} |
|
push(@{$responseTypeHash{$partIdSoFar}}, |
|
$responseType); |
} |
} |
} |
} |
} |
} |