version 1.515, 2016/03/02 14:14:06
|
version 1.532, 2017/07/10 13:01:39
|
Line 51 described at http://www.lon-capa.org.
|
Line 51 described at http://www.lon-capa.org.
|
X<lonnavmaps, overview> When a user enters a course, LON-CAPA examines the |
X<lonnavmaps, overview> When a user enters a course, LON-CAPA examines the |
course structure and caches it in what is often referred to as the |
course structure and caches it in what is often referred to as the |
"big hash" X<big hash>. You can see it if you are logged into |
"big hash" X<big hash>. You can see it if you are logged into |
LON-CAPA, in a course, by going to /adm/test. (You may need to |
LON-CAPA, in a course, by going to /adm/test. The content of |
tweak the /home/httpd/lonTabs/htpasswd file to view it.) The |
the hash will be under the heading "Big Hash". |
content of the hash will be under the heading "Big Hash". |
|
|
Access to /adm/test is controlled by a domain configuration, |
|
which a Domain Coordinator will set for a server's default domain |
|
via: Main Menu > Set domain configuration > Display (Access to |
|
server status pages checked), and entering a username:domain |
|
or IP address in the "Show user environment" row. Users with |
|
an unexpired domain coordinator role in the server's domain |
|
automatically receive access to /adm/test. |
|
|
Big Hash contains, among other things, how resources are related |
Big Hash contains, among other things, how resources are related |
to each other (next/previous), what resources are maps, which |
to each other (next/previous), what resources are maps, which |
Line 77 Apache::lonnavmaps also provides fairly
|
Line 84 Apache::lonnavmaps also provides fairly
|
rendering navmaps, and last but not least, provides the navmaps |
rendering navmaps, and last but not least, provides the navmaps |
view for when the user clicks the NAV button. |
view for when the user clicks the NAV button. |
|
|
B<Note>: Apache::lonnavmaps I<only> works for the "currently |
B<Note>: Apache::lonnavmaps by default will show information |
logged in user"; if you want things like "due dates for another |
for the "currently logged in user". However, if information |
student" lonnavmaps can not directly retrieve information like |
about resources is needed for a different user, e.g., a bubblesheet |
that. You need the EXT function. This module can still help, |
exam which uses randomorder, or randompick needs to be printed or |
because many things, such as the course structure, are constant |
graded for named user(s) or specific CODEs, then the username, |
|
domain, or CODE can be passed as arguments when creating a new |
|
navmap object. |
|
|
|
Note if you want things like "due dates for another student, |
|
you would use the EXT function instead of lonnavmaps. |
|
That said, the lonnavmaps module can still help, because many |
|
things, such as the course structure, are usually constant |
between users, and Apache::lonnavmaps can help by providing |
between users, and Apache::lonnavmaps can help by providing |
symbs for the EXT call. |
symbs for the EXT call. |
|
|
Line 91 all, then documents the Apache::lonnavma
|
Line 105 all, then documents the Apache::lonnavma
|
is the key to accessing the Big Hash information, covers the use |
is the key to accessing the Big Hash information, covers the use |
of the Iterator (which provides the logic for traversing the |
of the Iterator (which provides the logic for traversing the |
somewhat-complicated Big Hash data structure), documents the |
somewhat-complicated Big Hash data structure), documents the |
Apache::lonnavmaps::Resource objects that are returned by |
Apache::lonnavmaps::Resource objects that are returned singularly |
|
by: getBySymb(), getById(), getByMapPc(), and getResourceByUrl() |
|
(can also be as an array), or in an array by retrieveResources(). |
|
|
=head1 Subroutine: render |
=head1 Subroutine: render |
|
|
Line 995 sub render_resource {
|
Line 1011 sub render_resource {
|
$linkopen = ""; |
$linkopen = ""; |
$linkclose = ""; |
$linkclose = ""; |
} |
} |
if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) && |
if (((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || |
|
(&Apache::lonnet::allowed('cev',$env{'request.course.id'}))) && |
($resource->symb=~/\_\_\_[^\_]+\_\_\_uploaded/)) { |
($resource->symb=~/\_\_\_[^\_]+\_\_\_uploaded/)) { |
if (!$params->{'map_no_edit_link'}) { |
if (!$params->{'map_no_edit_link'}) { |
my $icon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png'; |
my $icon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png'; |
Line 1005 sub render_resource {
|
Line 1022 sub render_resource {
|
'</a>'; |
'</a>'; |
} |
} |
} |
} |
} |
if ($params->{'mapHidden'} || $resource->randomout()) { |
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
if ($resource->randomout()) { |
} |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
} else { |
|
if ($resource->randomout()) { |
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
|
} |
} |
} |
if (!$resource->condval()) { |
if (!$resource->condval()) { |
$nonLinkedText .= ' <span class="LC_info">('.&mt('conditionally hidden').')</span> '; |
$nonLinkedText .= ' <span class="LC_info">('.&mt('conditionally hidden').')</span> '; |
Line 1537 END
|
Line 1557 END
|
$result.='</form>'; |
$result.='</form>'; |
} |
} |
if (($args->{'caller'} eq 'navmapsdisplay') && |
if (($args->{'caller'} eq 'navmapsdisplay') && |
(&Apache::lonnet::allowed('mdc',$env{'request.course.id'}))) { |
((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || |
|
(&Apache::lonnet::allowed('cev',$env{'request.course.id'})))) { |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
if ($env{'course.'.$env{'request.course.id'}.'.url'} eq |
if ($env{'course.'.$env{'request.course.id'}.'.url'} eq |
Line 1583 END
|
Line 1604 END
|
$args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='$location' alt='' />"); |
$args->{'indentString'} = setDefault($args->{'indentString'}, "<img src='$location' alt='' />"); |
$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. |
# since structure actually doesn't matter, except what map has what resources. |
# We also do this even if $args->{'suppressEmptySequences'} |
if ($args->{'suppressEmptySequences'}) { |
# is not true, so we can hide empty sequences for which the |
my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, |
# hiddenresource parameter is set to yes (at map level), or |
$it->{FIRST_RESOURCE}, |
# mark as hidden for users who have $userCanSeeHidden. |
$it->{FINISH_RESOURCE}, |
# Use DFS for speed, since structure actually doesn't matter, |
{}, undef, 1); |
# except what map has what resources. |
my $depth = 0; |
|
$dfsit->next(); |
my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, |
my $curRes = $dfsit->next(); |
$it->{FIRST_RESOURCE}, |
while ($depth > -1) { |
$it->{FINISH_RESOURCE}, |
if ($curRes == $dfsit->BEGIN_MAP()) { $depth++; } |
{}, undef, 1); |
if ($curRes == $dfsit->END_MAP()) { $depth--; } |
my $depth = 0; |
|
$dfsit->next(); |
if (ref($curRes)) { |
my $curRes = $dfsit->next(); |
# Parallel pre-processing: Do sequences have non-filtered-out children? |
while ($depth > -1) { |
if ($curRes->is_map()) { |
if ($curRes == $dfsit->BEGIN_MAP()) { $depth++; } |
$curRes->{DATA}->{HAS_VISIBLE_CHILDREN} = 0; |
if ($curRes == $dfsit->END_MAP()) { $depth--; } |
# Sequences themselves do not count as visible children, |
|
# unless those sequences also have visible children. |
if (ref($curRes)) { |
# This means if a sequence appears, there's a "promise" |
# Parallel pre-processing: Do sequences have non-filtered-out children? |
# that there's something under it if you open it, somewhere. |
if ($curRes->is_map()) { |
} else { |
$curRes->{DATA}->{HAS_VISIBLE_CHILDREN} = 0; |
# Not a sequence: if it's filtered, ignore it, otherwise |
# Sequences themselves do not count as visible children, |
# rise up the stack and mark the sequences as having children |
# unless those sequences also have visible children. |
if (&$filterFunc($curRes)) { |
# This means if a sequence appears, there's a "promise" |
for my $sequence (@{$dfsit->getStack()}) { |
# that there's something under it if you open it, somewhere. |
$sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1; |
} elsif ($curRes->src()) { |
} |
# Not a sequence: if it's filtered, ignore it, otherwise |
|
# rise up the stack and mark the sequences as having children |
|
if (&$filterFunc($curRes)) { |
|
for my $sequence (@{$dfsit->getStack()}) { |
|
$sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1; |
} |
} |
} |
} |
} |
} |
} continue { |
|
$curRes = $dfsit->next(); |
|
} |
} |
|
} continue { |
|
$curRes = $dfsit->next(); |
} |
} |
|
|
my $displayedJumpMarker = 0; |
my $displayedJumpMarker = 0; |
Line 1675 END
|
Line 1700 END
|
undef($args->{'sort'}); |
undef($args->{'sort'}); |
} |
} |
|
|
|
# Determine if page will be served with https in case |
|
# it contains a syllabus which uses an external URL |
|
# which points at an http site. |
|
|
|
my ($is_ssl,$cdom,$cnum,$hostname); |
|
if ($ENV{'SERVER_PORT'} == 443) { |
|
$is_ssl = 1; |
|
if ($r) { |
|
$hostname = $r->hostname(); |
|
} else { |
|
$hostname = $ENV{'SERVER_NAME'}; |
|
} |
|
} |
|
if ($env{'request.course.id'}) { |
|
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
} |
|
|
while (1) { |
while (1) { |
if ($args->{'sort'}) { |
if ($args->{'sort'}) { |
Line 1710 END
|
Line 1752 END
|
} |
} |
|
|
# If this is an empty sequence and we're filtering them, continue on |
# If this is an empty sequence and we're filtering them, continue on |
if ($curRes->is_map() && $args->{'suppressEmptySequences'} && |
$args->{'mapHidden'} = 0; |
!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN}) { |
if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) { |
next; |
if ($args->{'suppressEmptySequences'}) { |
|
next; |
|
} else { |
|
my $mapname = &Apache::lonnet::declutter($curRes->src()); |
|
$mapname = &Apache::lonnet::deversion($mapname); |
|
if (lc($navmap->get_mapparam(undef,$mapname,"0.hiddenresource")) eq 'yes') { |
|
if ($userCanSeeHidden) { |
|
$args->{'mapHidden'} = 1; |
|
} else { |
|
next; |
|
} |
|
} |
|
} |
} |
} |
|
|
# If we're suppressing navmaps and this is a navmap, continue on |
# If we're suppressing navmaps and this is a navmap, continue on |
Line 1796 END
|
Line 1850 END
|
$stack=$it->getStack(); |
$stack=$it->getStack(); |
} |
} |
($src,$symb,$anchor)=getLinkForResource($stack); |
($src,$symb,$anchor)=getLinkForResource($stack); |
|
my $srcHasQuestion = $src =~ /\?/; |
|
if ($env{'request.course.id'}) { |
|
if (($is_ssl) && ($src =~ m{^\Q/public/$cdom/$cnum/syllabus\E($|\?)}) && |
|
($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { |
|
if ($hostname ne '') { |
|
$src = 'http://'.$hostname.$src; |
|
} |
|
$src .= ($srcHasQuestion? '&' : '?') . 'usehttp=1'; |
|
$srcHasQuestion = 1; |
|
} elsif (($is_ssl) && ($src =~ m{^\Q/adm/wrapper/ext/\E(?!https:)})) { |
|
if ($hostname ne '') { |
|
$src = 'http://'.$hostname.$src; |
|
} |
|
} |
|
} |
if (defined($anchor)) { $anchor='#'.$anchor; } |
if (defined($anchor)) { $anchor='#'.$anchor; } |
my $srcHasQuestion = $src =~ /\?/; |
|
$args->{"resourceLink"} = $src. |
$args->{"resourceLink"} = $src. |
($srcHasQuestion?'&':'?') . |
($srcHasQuestion?'&':'?') . |
'symb=' . &escape($symb).$anchor; |
'symb=' . &escape($symb).$anchor; |
Line 2667 sub parmval_real {
|
Line 2735 sub parmval_real {
|
} |
} |
foreach my $item (@recurseup) { |
foreach my $item (@recurseup) { |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
last if (defined($$useropt{$norecursechk})); |
if (defined($$useropt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return [$$useropt{$norecursechk},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
if (defined($$useropt{$recursechk})) { return [$$useropt{$recursechk},'map']; } |
if (defined($$useropt{$recursechk})) { return [$$useropt{$recursechk},'map']; } |
} |
} |
Line 2685 sub parmval_real {
|
Line 2759 sub parmval_real {
|
} |
} |
foreach my $item (@recurseup) { |
foreach my $item (@recurseup) { |
my $norecursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(all).'.$what; |
my $norecursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(all).'.$what; |
last if (defined($$courseopt{$norecursechk})); |
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return [$$courseopt{$norecursechk},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
my $recursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(rec).'.$what; |
my $recursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(rec).'.$what; |
if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; } |
if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; } |
} |
} |
Line 2702 sub parmval_real {
|
Line 2782 sub parmval_real {
|
} |
} |
foreach my $item (@recurseup) { |
foreach my $item (@recurseup) { |
my $norecursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(all).'.$what; |
my $norecursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(all).'.$what; |
last if (defined($$courseopt{$norecursechk})); |
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return [$$courseopt{$norecursechk},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
my $recursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what; |
my $recursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what; |
if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; } |
if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; } |
} |
} |
Line 2736 sub parmval_real {
|
Line 2822 sub parmval_real {
|
} |
} |
foreach my $item (@recurseup) { |
foreach my $item (@recurseup) { |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
last if (defined($$courseopt{$norecursechk})); |
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return [$$courseopt{$norecursechk},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
if (defined($$courseopt{$recursechk})) { |
if (defined($$courseopt{$recursechk})) { |
return [$$courseopt{$recursechk},'map']; |
return [$$courseopt{$recursechk},'map']; |
Line 2768 sub parmval_real {
|
Line 2860 sub parmval_real {
|
sub recurseup_maps { |
sub recurseup_maps { |
my ($self,$mapname) = @_; |
my ($self,$mapname) = @_; |
my @recurseup; |
my @recurseup; |
my @pcs = split(/,/,$self->getResourceByUrl(&Apache::lonnet::clutter($mapname))->map_hierarchy()); |
if ($mapname) { |
shift(@pcs); |
my $res = $self->getResourceByUrl($mapname); |
pop(@pcs); |
if (ref($res)) { |
if (@pcs) { |
my @pcs = split(/,/,$res->map_hierarchy()); |
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); |
shift(@pcs); |
|
if (@pcs) { |
|
@recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); |
|
} |
|
} |
} |
} |
return @recurseup; |
return @recurseup; |
} |
} |
Line 2788 sub map_printdates {
|
Line 2884 sub map_printdates {
|
|
|
|
|
|
|
my $opendate = $self->get_mapparam($res->symb(), "$part.printstartdate"); |
my $opendate = $self->get_mapparam($res->symb(),'',"$part.printstartdate"); |
my $closedate= $self->get_mapparam($res->symb(), "$part.printenddate"); |
my $closedate= $self->get_mapparam($res->symb(),'',"$part.printenddate"); |
|
|
|
|
return ($opendate, $closedate); |
return ($opendate, $closedate); |
} |
} |
|
|
sub get_mapparam { |
sub get_mapparam { |
my ($self, $symb, $what) = @_; |
my ($self, $symb, $mapname, $what) = @_; |
|
|
# Ensure the course option hash is populated: |
# Ensure the course option hash is populated: |
|
|
Line 2815 sub get_mapparam {
|
Line 2911 sub get_mapparam {
|
my $uname=$self->{USERNAME}; |
my $uname=$self->{USERNAME}; |
my $udom=$self->{DOMAIN}; |
my $udom=$self->{DOMAIN}; |
|
|
unless ($symb) { return ['']; } |
unless ($symb || $mapname) { return; } |
my $result=''; |
my $result=''; |
|
my ($recursed,@recurseup); |
|
|
|
|
# Figure out which map we are in. |
# Figure out which map we are in. |
|
|
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
if ($symb && !$mapname) { |
$mapname = &Apache::lonnet::deversion($mapname); |
my ($id,$fn); |
|
($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
|
$mapname = &Apache::lonnet::deversion($mapname); |
|
} |
|
|
|
|
my $rwhat=$what; |
my $rwhat=$what; |
Line 2831 sub get_mapparam {
|
Line 2931 sub get_mapparam {
|
|
|
# Build the hash keys for the lookup: |
# Build the hash keys for the lookup: |
|
|
my $symbparm=$symb.'.'.$what; |
|
my $mapparm=$mapname.'___(all).'.$what; |
my $mapparm=$mapname.'___(all).'.$what; |
my $recurseparm=$mapname.'___(rec).'.$what; |
my $recurseparm=$mapname.'___(rec).'.$what; |
my $usercourseprefix=$cid; |
my $usercourseprefix=$cid; |
Line 2862 sub get_mapparam {
|
Line 2961 sub get_mapparam {
|
if (defined($$useropt{$courseleveli})) { |
if (defined($$useropt{$courseleveli})) { |
return $$useropt{$courseleveli}; |
return $$useropt{$courseleveli}; |
} |
} |
|
unless ($recursed) { |
|
@recurseup = $self->recurseup_maps($mapname); |
|
$recursed = 1; |
|
} |
|
foreach my $item (@recurseup) { |
|
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
|
if (defined($$useropt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return $$useropt{$norecursechk}; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
|
if (defined($$useropt{$recursechk})) { |
|
return $$useropt{$recursechk}; |
|
} |
|
} |
} |
} |
|
|
# Check course -- group |
# Check course -- group |
Line 2875 sub get_mapparam {
|
Line 2992 sub get_mapparam {
|
if (defined($$courseopt{$grpleveli})) { |
if (defined($$courseopt{$grpleveli})) { |
return $$courseopt{$grpleveli}; |
return $$courseopt{$grpleveli}; |
} |
} |
|
unless ($recursed) { |
|
@recurseup = $self->recurseup_maps($mapname); |
|
$recursed = 1; |
|
} |
|
foreach my $item (@recurseup) { |
|
my $norecursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(all).'.$what; |
|
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return $$courseopt{$norecursechk}; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(rec).'.$what; |
|
if (defined($$courseopt{$recursechk})) { |
|
return $$courseopt{$recursechk}; |
|
} |
|
} |
} |
} |
|
|
# Check course -- section |
# Check course -- section |
|
|
|
|
if ($csec and defined($courseopt)) { |
if ($csec ne '' and defined($courseopt)) { |
if (defined($$courseopt{$seclevelm})) { |
if (defined($$courseopt{$seclevelm})) { |
return $$courseopt{$seclevelm}; |
return $$courseopt{$seclevelm}; |
} |
} |
if (defined($$courseopt{$secleveli})) { |
if (defined($$courseopt{$secleveli})) { |
return $$courseopt{$secleveli}; |
return $$courseopt{$secleveli}; |
} |
} |
|
unless ($recursed) { |
|
@recurseup = $self->recurseup_maps($mapname); |
|
$recursed = 1; |
|
} |
|
foreach my $item (@recurseup) { |
|
my $norecursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(all).'.$what; |
|
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return $$courseopt{$norecursechk}; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what; |
|
if (defined($$courseopt{$recursechk})) { |
|
return $$courseopt{$recursechk}; |
|
} |
|
} |
} |
} |
# Check the map parameters themselves: |
# Check the map parameters themselves: |
|
|
my $thisparm = $$parmhash{$symbparm}; |
if ($symb) { |
if (defined($thisparm)) { |
my $symbparm=$symb.'.'.$what; |
return $thisparm; |
my $thisparm = $$parmhash{$symbparm}; |
|
if (defined($thisparm)) { |
|
return $thisparm; |
|
} |
} |
} |
|
|
|
|
Line 2902 sub get_mapparam {
|
Line 3058 sub get_mapparam {
|
if (defined($$courseopt{$courselevelm})) { |
if (defined($$courseopt{$courselevelm})) { |
return $$courseopt{$courselevelm}; |
return $$courseopt{$courselevelm}; |
} |
} |
|
unless ($recursed) { |
|
@recurseup = $self->recurseup_maps($mapname); |
|
$recursed = 1; |
|
} |
|
if (@recurseup) { |
|
foreach my $item (@recurseup) { |
|
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
|
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return $$courseopt{$norecursechk}; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
|
if (defined($$courseopt{$recursechk})) { |
|
return $$courseopt{$recursechk}; |
|
} |
|
} |
|
} |
} |
} |
return undef; # Unefined if we got here. |
return undef; # Undefined if we got here. |
} |
} |
|
|
sub course_printdates { |
sub course_printdates { |
Line 4073 sub enclosing_map_src {
|
Line 4249 sub enclosing_map_src {
|
} |
} |
sub symb { |
sub symb { |
my $self=shift; |
my $self=shift; |
|
if (defined $self->{SYMB}) { return $self->{SYMB}; } |
(my $first, my $second) = $self->{ID} =~ /(\d+).(\d+)/; |
(my $first, my $second) = $self->{ID} =~ /(\d+).(\d+)/; |
my $symbSrc = &Apache::lonnet::declutter($self->src()); |
my $symbSrc = &Apache::lonnet::declutter($self->src()); |
my $symb = &Apache::lonnet::declutter($self->navHash('map_id_'.$first)) |
my $symb = &Apache::lonnet::declutter($self->navHash('map_id_'.$first)) |
Line 4602 sub duedate {
|
Line 4779 sub duedate {
|
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[0] =~ /\d+/) { |
if ($interval[0] =~ /^(\d+)/) { |
my $first_access=&Apache::lonnet::get_first_access($interval[1], |
my $timelimit = $1; |
$self->{SYMB}); |
my $first_access=&Apache::lonnet::get_first_access($interval[1], |
|
$self->{SYMB}); |
if (defined($first_access)) { |
if (defined($first_access)) { |
my $interval = $first_access+$interval[0]; |
my $interval = $first_access+$timelimit; |
$date = (!$due_date || $interval < $due_date) ? $interval |
$date = (!$due_date || $interval < $due_date) ? $interval |
: $due_date; |
: $due_date; |
} else { |
} else { |
Line 4706 sub getReturnHash {
|
Line 4884 sub getReturnHash {
|
my $self = shift; |
my $self = shift; |
|
|
if (!defined($self->{RETURN_HASH})) { |
if (!defined($self->{RETURN_HASH})) { |
my %tmpHash = &Apache::lonnet::restore($self->{SYMB},undef,$self->{DOMAIN},$self->{USERNAME}); |
#my %tmpHash = &Apache::lonnet::restore($self->{SYMB},undef,$self->{DOMAIN},$self->{USERNAME}); |
$self->{RETURN_HASH} = \%tmpHash; |
#$self->{RETURN_HASH} = \%tmpHash; |
|
# When info is retrieved for several resources (as when rendering a directory), |
|
# it is much faster to use the user profile dump and avoid repeated lonnet requests |
|
# (especially since lonnet::currentdump is using Lond directly whenever possible, |
|
# and lonnet::restore is not at this point). |
|
$self->{NAV_MAP}->get_user_data(); |
|
$self->{RETURN_HASH} = $self->{NAV_MAP}->{STUDENT_DATA}->{$self->{SYMB}}; |
} |
} |
} |
} |
|
|
Line 4938 sub extractParts {
|
Line 5122 sub extractParts {
|
my %parts; |
my %parts; |
|
|
# Retrieve part count, if this is a problem |
# Retrieve part count, if this is a problem |
if ($self->is_problem()) { |
if ($self->is_raw_problem()) { |
my $partorder = &Apache::lonnet::metadata($self->src(), 'partorder'); |
my $partorder = &Apache::lonnet::metadata($self->src(), 'partorder'); |
my $metadata = &Apache::lonnet::metadata($self->src(), 'packages'); |
my $metadata = &Apache::lonnet::metadata($self->src(), 'packages'); |
|
|
Line 5482 sub check_for_slot {
|
Line 5666 sub check_for_slot {
|
my $cnum=$env{'course.'.$cid.'.num'}; |
my $cnum=$env{'course.'.$cid.'.num'}; |
my $now = time; |
my $now = time; |
my $num_usable_slots = 0; |
my $num_usable_slots = 0; |
|
my ($checkedin,$checkedinslot,%consumed_uniq,%slots); |
if (@slots > 0) { |
if (@slots > 0) { |
my %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum); |
%slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum); |
if (&Apache::lonnet::error(%slots)) { |
if (&Apache::lonnet::error(%slots)) { |
return (UNKNOWN); |
return (UNKNOWN); |
} |
} |
my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots,'starttime'); |
my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots,'starttime'); |
my ($checkedin,$checkedinslot); |
|
foreach my $slot_name (@sorted_slots) { |
foreach my $slot_name (@sorted_slots) { |
next if (!defined($slots{$slot_name}) || !ref($slots{$slot_name})); |
next if (!defined($slots{$slot_name}) || !ref($slots{$slot_name})); |
my $end = $slots{$slot_name}->{'endtime'}; |
my $end = $slots{$slot_name}->{'endtime'}; |
Line 5522 sub check_for_slot {
|
Line 5706 sub check_for_slot {
|
$num_usable_slots ++; |
$num_usable_slots ++; |
} |
} |
} |
} |
my ($is_correct,$got_grade); |
my ($is_correct,$wait_for_grade); |
if ($self->is_task()) { |
if ($self->is_task()) { |
my $taskstatus = $self->taskstatus(); |
my $taskstatus = $self->taskstatus(); |
$is_correct = (($taskstatus eq 'pass') || |
$is_correct = (($taskstatus eq 'pass') || |
($self->solved() =~ /^correct_/)); |
($self->solved() =~ /^correct_/)); |
$got_grade = ($taskstatus =~ /^(?:pass|fail)$/); |
unless ($taskstatus =~ /^(?:pass|fail)$/) { |
|
$wait_for_grade = 1; |
|
} |
} else { |
} else { |
$got_grade = 1; |
unless ($self->completable()) { |
$is_correct = ($self->solved() =~ /^correct_/); |
$wait_for_grade = 1; |
|
} |
|
unless (($self->problemstatus($part) eq 'no') || |
|
($self->problemstatus($part) eq 'no_feedback_ever')) { |
|
$is_correct = ($self->solved($part) =~ /^correct_/); |
|
$wait_for_grade = 0; |
|
} |
} |
} |
($checkedin,$checkedinslot) = $self->checkedin(); |
($checkedin,$checkedinslot) = $self->checkedin(); |
if ($checkedin) { |
if ($checkedin) { |
if (!$got_grade) { |
if (ref($slots{$checkedinslot}) eq 'HASH') { |
|
$consumed_uniq{$checkedinslot} = $slots{$checkedinslot}{'uniqueperiod'}; |
|
} |
|
if ($wait_for_grade) { |
return (WAITING_FOR_GRADE); |
return (WAITING_FOR_GRADE); |
} elsif ($is_correct) { |
} elsif ($is_correct) { |
return (CORRECT); |
return (CORRECT); |
Line 5572 sub check_for_slot {
|
Line 5767 sub check_for_slot {
|
} |
} |
} |
} |
if ($canuse) { |
if ($canuse) { |
|
if ($checkedin) { |
|
if (ref($consumed_uniq{$checkedinslot}) eq 'ARRAY') { |
|
my ($uniqstart,$uniqend)=@{$consumed_uniq{$checkedinslot}}; |
|
if ($reservable->{'now'}{$slot}{'uniqueperiod'} =~ /^(\d+),(\d+)$/) { |
|
my ($new_uniq_start,$new_uniq_end) = ($1,$2); |
|
next if (! |
|
($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) || |
|
($uniqstart > $new_uniq_end && $uniqend > $new_uniq_end )); |
|
} |
|
} |
|
} |
return(RESERVABLE,$reservable->{'now'}{$slot}{'endreserve'}); |
return(RESERVABLE,$reservable->{'now'}{$slot}{'endreserve'}); |
} |
} |
} |
} |
Line 5602 sub check_for_slot {
|
Line 5808 sub check_for_slot {
|
$canuse = 1; |
$canuse = 1; |
} |
} |
if ($canuse) { |
if ($canuse) { |
|
if ($checkedin) { |
|
if (ref($consumed_uniq{$checkedinslot}) eq 'ARRAY') { |
|
my ($uniqstart,$uniqend)=@{$consumed_uniq{$checkedinslot}}; |
|
if ($reservable->{'future'}{$slot}{'uniqueperiod'} =~ /^(\d+),(\d+)$/) { |
|
my ($new_uniq_start,$new_uniq_end) = ($1,$2); |
|
next if (! |
|
($uniqstart < $new_uniq_start && $uniqend < $new_uniq_start) || |
|
($uniqstart > $new_uniq_end && $uniqend > $new_uniq_end )); |
|
} |
|
} |
|
} |
return(RESERVABLE_LATER,$reservable->{'future'}{$slot}{'startreserve'}); |
return(RESERVABLE_LATER,$reservable->{'future'}{$slot}{'startreserve'}); |
} |
} |
} |
} |