version 1.428, 2009/02/25 15:25:21
|
version 1.436, 2009/10/22 03:04:21
|
Line 31
|
Line 31
|
|
|
=head1 NAME |
=head1 NAME |
|
|
Apache::lonnavmaps.pm |
Apache::lonnavmaps - Subroutines to handle and render the navigation |
|
|
=head1 SYNOPSIS |
=head1 SYNOPSIS |
|
|
Line 530 my %colormap =
|
Line 530 my %colormap =
|
# is not yet done and due in less than 24 hours |
# is not yet done and due in less than 24 hours |
my $hurryUpColor = "#FF0000"; |
my $hurryUpColor = "#FF0000"; |
|
|
|
my $future_slots_checked = 0; |
|
my $future_slots = 0; |
|
|
sub close { |
sub close { |
if ($env{'environment.remotenavmap'} ne 'on') { return ''; } |
if ($env{'environment.remotenavmap'} ne 'on') { return ''; } |
return(<<ENDCLOSE); |
return(<<ENDCLOSE); |
Line 634 sub getDescription {
|
Line 637 sub getDescription {
|
if ($status == $res->OPEN_LATER) { |
if ($status == $res->OPEN_LATER) { |
return &mt("Open ") .timeToHumanString($open,'start'); |
return &mt("Open ") .timeToHumanString($open,'start'); |
} |
} |
|
if ($res->simpleStatus($part) == $res->OPEN) { |
|
unless (&Apache::lonnet::allowed('mgr',$env{'request.course.id'})) { |
|
my ($slot_status,$slot_time,$slot_name)=$res->check_for_slot($part); |
|
if ($slot_status == $res->UNKNOWN) { |
|
return &mt('Reservation status unknown'); |
|
} elsif ($slot_status == $res->RESERVED) { |
|
return &mt('Reserved - ends [_1]', |
|
timeToHumanString($slot_time,'end')); |
|
} elsif ($slot_status == $res->RESERVED_LOCATION) { |
|
return &mt('Reserved - specific location(s) - ends [_1]', |
|
timeToHumanString($slot_time,'end')); |
|
} elsif ($slot_status == $res->RESERVED_LATER) { |
|
return &mt('Reserved - next open [_1]', |
|
timeToHumanString($slot_time,'start')); |
|
} elsif ($slot_status == $res->RESERVABLE) { |
|
return &mt('Reservable ending [_1]', |
|
timeToHumanString($slot_time,'end')); |
|
} elsif ($slot_status == $res->RESERVABLE_LATER) { |
|
return &mt('Reservable starting [_1]', |
|
timeToHumanString($slot_time,'start')); |
|
} elsif ($slot_status == $res->NOT_IN_A_SLOT) { |
|
return &mt('Reserve a time/place to work'); |
|
} elsif ($slot_status == $res->NOTRESERVABLE) { |
|
return &mt('Reservation not available'); |
|
} elsif ($slot_status == $res->WAITING_FOR_GRADE) { |
|
return &mt('Submission in grading queue'); |
|
} |
|
} |
|
} |
if ($status == $res->OPEN) { |
if ($status == $res->OPEN) { |
if ($due) { |
if ($due) { |
if ($res->is_practice()) { |
if ($res->is_practice()) { |
Line 848 sub render_resource {
|
Line 880 sub render_resource {
|
my $link = $params->{"resourceLink"}; |
my $link = $params->{"resourceLink"}; |
|
|
# The URL part is not escaped at this point, but the symb is... |
# The URL part is not escaped at this point, but the symb is... |
# The stuff to the left of the ? must have ' replaced by \' since |
|
# it will be quoted with ' in the href. |
|
|
|
my ($left,$right) = split(/\?/, $link); |
|
$link = $left.'?'.$right; |
|
|
|
my $src = $resource->src(); |
my $src = $resource->src(); |
my $it = $params->{"iterator"}; |
my $it = $params->{"iterator"}; |
Line 865 sub render_resource {
|
Line 892 sub render_resource {
|
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons"); |
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='$location/branch.gif' alt='Branch' />"; |
$newBranchText = "<img src='$location/branch.gif' alt=".mt('Branch')." />"; |
} |
} |
|
|
# links to open and close the folder |
# links to open and close the folder |
Line 962 sub render_resource {
|
Line 989 sub render_resource {
|
# Is this the current resource? |
# Is this the current resource? |
if (!$params->{'displayedHereMarker'} && |
if (!$params->{'displayedHereMarker'} && |
$resource->symb() eq $params->{'here'} ) { |
$resource->symb() eq $params->{'here'} ) { |
$curMarkerBegin = '<em style="font-weight:bold;">'; |
$curMarkerBegin = '<em>'; |
$curMarkerEnd = '</em>'; |
$curMarkerEnd = '</em>'; |
$params->{'displayedHereMarker'} = 1; |
$params->{'displayedHereMarker'} = 1; |
} |
} |
Line 1387 sub render {
|
Line 1414 sub render {
|
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); |
if ($navmap->{LAST_CHECK}) { |
if ($navmap->{LAST_CHECK}) { |
$result .= |
$result .= |
'<img src="'.$location.'/chat.gif"> '.&mt('New discussion since').' '. |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('New discussion since').' '. |
strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). |
strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). |
'</td><td align="center" valign="bottom"> '. |
'</td><td align="center" valign="bottom"> '. |
'<img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)').'<p>'. |
'<img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)').'<p>'. |
'</td>'; |
'</td>'; |
} else { |
} else { |
$result .= '<td align="center" valign="bottom"> '. |
$result .= '<td align="center" valign="bottom"> '. |
'<img src="'.$location.'/chat.gif"> '.&mt('Discussions').'</td><td align="center" valign="bottom">'. |
'<img src="'.$location.'/chat.gif" alt="" /> '.&mt('Discussions').'</td><td align="center" valign="bottom">'. |
' <img src="'.$location.'/feedback.gif"> '.&mt('New message (click to open)'). |
' <img src="'.$location.'/feedback.gif" alt="" /> '.&mt('New message (click to open)'). |
'</td>'; |
'</td>'; |
} |
} |
|
|
Line 1463 END
|
Line 1490 END
|
} else { |
} else { |
$result .= '</tr><tr>'; |
$result .= '</tr><tr>'; |
} |
} |
$result.=&show_linkitems($args->{'linkitems'}); |
$result.="<td class=\"LC_middle\">".mt('Tools:')."</td>"; |
|
$result.=&show_linkitems_toolbar($args->{'linkitems'}); |
if ($args->{'sort_html'}) { |
if ($args->{'sort_html'}) { |
if ($env{'environment.remotenavmap'} ne 'on') { |
if ($env{'environment.remotenavmap'} ne 'on') { |
$result.='<td> </td><td> </td><td> </td>'. |
$result.='<td> </td><td> </td><td> </td>'. |
Line 1486 END
|
Line 1514 END
|
} |
} |
# End parameter setting |
# End parameter setting |
|
|
$result .= "\n<table id=\"LC_nav_location\">\n<tbody>\n<tr>\n<td class=\"LC_current_location\"> </td>\n</tr>\n</tbody>\n</table>\n"; |
|
$result .= "<br />\n"; |
$result .= "<br />\n"; |
|
|
# Data |
# Data |
$result .= '<table id="LC_tableOfContent">' ."\n"; |
$result.=&Apache::loncommon::start_data_table("LC_tableOfContent"); |
|
|
my $res = "Apache::lonnavmaps::resource"; |
my $res = "Apache::lonnavmaps::resource"; |
my %condenseStatuses = |
my %condenseStatuses = |
Line 1734 END
|
Line 1761 END
|
$rownum ++; |
$rownum ++; |
my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)]; |
my $backgroundColor = $backgroundColors[$rownum % scalar(@backgroundColors)]; |
|
|
$result .= " <tr class='$backgroundColor'>\n"; |
$result .= &Apache::loncommon::start_data_table_row(); |
|
|
# Set up some data about the parts that the cols might want |
# Set up some data about the parts that the cols might want |
my $filter = $it->{FILTER}; |
my $filter = $it->{FILTER}; |
Line 1760 END
|
Line 1787 END
|
} |
} |
$result .= $colHTML . "\n"; |
$result .= $colHTML . "\n"; |
} |
} |
$result .= " </tr>\n"; |
$result .= &Apache::loncommon::end_data_table_row(); |
$args->{'isNewBranch'} = 0; |
$args->{'isNewBranch'} = 0; |
} |
} |
|
|
Line 1796 if (location.href.indexOf('#curloc')==-1
|
Line 1823 if (location.href.indexOf('#curloc')==-1
|
</script>"; |
</script>"; |
} |
} |
|
|
$result .= "</table>"; |
$result.=&Apache::loncommon::end_data_table(); |
|
|
if ($r) { |
if ($r) { |
$r->print($result); |
$r->print($result); |
$result = ""; |
$result = ""; |
Line 1847 ENDBLOCK
|
Line 1874 ENDBLOCK
|
return $result; |
return $result; |
} |
} |
|
|
|
sub show_linkitems_toolbar { |
|
my ($linkitems,$condition)=@_; |
|
my @linkorder = ("blank","launchnav","closenav","firsthomework", |
|
"everything","uncompleted","changefolder","clearbubbles"); |
|
|
|
my $result .=' |
|
<td align="left"> |
|
<span class="LC_nobreak">'."\n<ul id=\"LC_toolbar\">"; |
|
foreach my $link (@linkorder) { |
|
my $link_id = "LC_content_toolbar_".$link; |
|
if (defined($linkitems->{$link})) { |
|
if ($linkitems->{$link}{'text'} ne '') { |
|
$linkitems->{$link}{'cmd'}=~s/"/'/g; |
|
if($linkitems->{$link}{'cmd'}){ |
|
if($link eq 'changefolder'){ |
|
if($condition){$link_id='LC_content_toolbar_changefolder_toggled'} |
|
else{$link_id='LC_content_toolbar_changefolder'} |
|
} |
|
$result .= ' <li><a href="#"'. |
|
' onClick="'.$linkitems->{$link}{'cmd'}.'"'. |
|
' id="'.$link_id.'"'. |
|
' class="LC_toolbarItem"'. |
|
' title="'.$linkitems->{$link}{'text'}.'"></a></li>'."\n"; |
|
} |
|
|
|
} |
|
} |
|
} |
|
$result .= '</ul>'; |
|
$result .= ' </span></td>'."\n"; |
|
|
|
return $result; |
|
} |
|
|
|
|
1; |
1; |
|
|
|
|
Line 3942 sub awarded {
|
Line 4004 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 taskversion { |
|
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.'.version'}; |
|
} |
|
sub taskstatus { |
|
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.'.$self->taskversion($part).'.'.$part.'.status'}; |
|
} |
|
sub solved { |
|
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.'.solved'}; |
|
} |
|
sub checkedin { |
|
my $self = shift; my $part = shift; |
|
$self->{NAV_MAP}->get_user_data(); |
|
if (!defined($part)) { $part = '0'; } |
|
if ($self->is_task()) { |
|
my $version = $self->taskversion($part); |
|
return ($self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$version .'.'.$part.'.checkedin'},$self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$version .'.'.$part.'.checkedin.slot'}); |
|
} else { |
|
return ($self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.checkedin'},$self->{NAV_MAP}->{STUDENT_DATA}->{$self->symb()}->{'resource.'.$part.'.checkedin.slot'}); |
|
} |
|
} |
# this should work exactly like the copy in lonhomework.pm |
# this should work exactly like the copy in lonhomework.pm |
sub duedate { |
sub duedate { |
(my $self, my $part) = @_; |
(my $self, my $part) = @_; |
Line 4037 sub part_display {
|
Line 4128 sub part_display {
|
} |
} |
return $display; |
return $display; |
} |
} |
|
sub slot_control { |
|
my $self=shift(); my $part = shift(); |
|
if (!defined($part)) { $part = '0'; } |
|
my $useslots = $self->parmval("useslots", $part); |
|
my $availablestudent = $self->parmval("availablestudent", $part); |
|
my $available = $self->parmval("available", $part); |
|
return ($useslots,$availablestudent,$available); |
|
} |
|
|
# Multiple things need this |
# Multiple things need this |
sub getReturnHash { |
sub getReturnHash { |
Line 4469 sub OPEN { return 1; }
|
Line 4568 sub OPEN { return 1; }
|
sub PAST_DUE_NO_ANSWER { return 2; } |
sub PAST_DUE_NO_ANSWER { return 2; } |
sub PAST_DUE_ANSWER_LATER { return 3; } |
sub PAST_DUE_ANSWER_LATER { return 3; } |
sub ANSWER_OPEN { return 4; } |
sub ANSWER_OPEN { return 4; } |
sub NOTHING_SET { return 5; } |
sub NOTHING_SET { return 5; } |
sub NETWORK_FAILURE { return 100; } |
sub NETWORK_FAILURE { return 100; } |
|
|
# getDateStatus gets the date status for a given problem part. |
# getDateStatus gets the date status for a given problem part. |
Line 4681 An answer has been submitted, but the st
|
Line 4780 An answer has been submitted, but the st
|
|
|
=cut |
=cut |
|
|
sub TRIES_LEFT { return 20; } |
sub TRIES_LEFT { return 20; } |
sub ANSWER_SUBMITTED { return 21; } |
sub ANSWER_SUBMITTED { return 21; } |
sub PARTIALLY_CORRECT{ return 22; } |
sub PARTIALLY_CORRECT { return 22; } |
|
|
|
sub RESERVED_LATER { return 30; } |
|
sub RESERVED { return 31; } |
|
sub RESERVED_LOCATION { return 32; } |
|
sub RESERVABLE { return 33; } |
|
sub RESERVABLE_LATER { return 34; } |
|
sub NOTRESERVABLE { return 35; } |
|
sub NOT_IN_A_SLOT { return 36; } |
|
sub NEEDS_CHECKIN { return 37; } |
|
sub WAITING_FOR_GRADE { return 38; } |
|
sub UNKNOWN { return 39; } |
|
|
sub status { |
sub status { |
my $self = shift; |
my $self = shift; |
Line 4776 sub status {
|
Line 4886 sub status {
|
return OPEN; |
return OPEN; |
} |
} |
|
|
|
sub check_for_slot { |
|
my $self = shift; |
|
my $part = shift; |
|
my ($use_slots,$available,$availablestudent) = $self->slot_control($part); |
|
if (($use_slots ne '') && ($use_slots !~ /^\s*no\s*$/i)) { |
|
my @slots = (split(/:/,$availablestudent),split(/:/,$available)); |
|
my $cid=$env{'request.course.id'}; |
|
my $cdom=$env{'course.'.$cid.'.domain'}; |
|
my $cnum=$env{'course.'.$cid.'.num'}; |
|
my $now = time; |
|
if (@slots > 0) { |
|
my %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum); |
|
if (&Apache::lonnet::error(%slots)) { |
|
return (UNKNOWN); |
|
} |
|
my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots); |
|
my ($checkedin,$checkedinslot); |
|
foreach my $slot_name (@sorted_slots) { |
|
next if (!defined($slots{$slot_name}) || |
|
!ref($slots{$slot_name})); |
|
my $end = $slots{$slot_name}->{'endtime'}; |
|
my $start = $slots{$slot_name}->{'starttime'}; |
|
my $ip = $slots{$slot_name}->{'ip'}; |
|
if ($self->simpleStatus() == OPEN) { |
|
my $startreserve = $slots{$slot_name}->{'startreserve'}; |
|
my @proctors; |
|
if ($slots{$slot_name}->{'proctor'} ne '') { |
|
@proctors = split(',',$slots{$slot_name}->{'proctor'}); |
|
} |
|
if ($end > $now) { |
|
($checkedin,$checkedinslot) = $self->checkedin(); |
|
if ($startreserve < $now) { |
|
if ($start > $now) { |
|
return (RESERVED_LATER,$start,$slot_name); |
|
} else { |
|
if ($ip ne '') { |
|
if (!&Apache::loncommon::check_ip_acc($ip)) { |
|
return (RESERVED_LOCATION,$ip,$slot_name); |
|
} |
|
} |
|
if (@proctors > 0) { |
|
unless ((grep(/^\Q$checkedin\E/,@proctors)) && |
|
($checkedinslot eq $slot_name)) { |
|
return (NEEDS_CHECKIN,undef,$slot_name); |
|
} |
|
} |
|
return (RESERVED,$end,$slot_name); |
|
} |
|
} else { |
|
if ($start > $now) { |
|
return (RESERVABLE,$startreserve,$slot_name); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
my ($is_correct,$got_grade); |
|
if ($self->is_task()) { |
|
my $taskstatus = $self->taskstatus(); |
|
$is_correct = (($taskstatus eq 'pass') || |
|
($self->solved() =~ /^correct_/)); |
|
$got_grade = ($self->solved() =~ /^(?:pass|fail)$/); |
|
} else { |
|
$got_grade = 1; |
|
$is_correct = ($self->solved() =~ /^correct_/); |
|
} |
|
($checkedin,$checkedinslot) = $self->checkedin(); |
|
if ($checkedin) { |
|
if (!$got_grade) { |
|
return (WAITING_FOR_GRADE); |
|
} elsif ($is_correct) { |
|
return (CORRECT); |
|
} |
|
} |
|
return(NOT_IN_A_SLOT); |
|
} else { |
|
if (!$future_slots_checked) { |
|
$future_slots = &get_future_slots($cdom,$cnum,$now); |
|
$future_slots_checked = 1; |
|
} |
|
if ($future_slots) { |
|
return(NOT_IN_A_SLOT); |
|
} |
|
return(NOTRESERVABLE); |
|
} |
|
} |
|
return; |
|
} |
|
|
|
sub get_future_slots { |
|
my ($cdom,$cnum,$now) = @_; |
|
my %slots=&Apache::lonnet::dump('slots',$cdom,$cnum); |
|
my $future_slots = 0; |
|
foreach my $slot (keys(%slots)) { |
|
if (($slots{$slot}->{'starttime'} > $now) && |
|
($slots{$slot}->{'endtime'} > $now)) { |
|
$future_slots ++; |
|
} |
|
} |
|
return $future_slots; |
|
} |
|
|
sub CLOSED { return 23; } |
sub CLOSED { return 23; } |
sub ERROR { return 24; } |
sub ERROR { return 24; } |
|
|