version 1.509.2.14.2.7, 2023/01/20 22:51:11
|
version 1.544, 2018/12/27 20:10:31
|
Line 2
|
Line 2
|
# Navigate Maps Handler |
# Navigate Maps Handler |
# |
# |
# $Id$ |
# $Id$ |
|
|
# |
# |
# Copyright Michigan State University Board of Trustees |
# Copyright Michigan State University Board of Trustees |
# |
# |
Line 52 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 65 processed.
|
Line 71 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 than 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 auxiliary 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 |
a given resource. |
a given resource. |
Line 78 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 92 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 342 user into thinking that if the sequence
|
Line 357 user into thinking that if the sequence
|
under it; for example, see the "Show Uncompleted Homework" view on the |
under it; for example, see the "Show Uncompleted Homework" view on the |
B<NAV> screen. |
B<NAV> screen. |
|
|
=item * B<suppressNavmap>: default: false |
=item * B<suppressNavmaps>: default: false |
|
|
If true, will not display Navigate Content resources. |
If true, will not display Navigate Content resources. |
|
|
Line 577 sub getLinkForResource {
|
Line 592 sub getLinkForResource {
|
my $anchor; |
my $anchor; |
if ($res->is_page()) { |
if ($res->is_page()) { |
foreach my $item (@$stack) { if (defined($item)) { $anchor = $item; } } |
foreach my $item (@$stack) { if (defined($item)) { $anchor = $item; } } |
if ($anchor->encrypted() && !&advancedUser()) { |
$anchor=&escape($anchor->shown_symb()); |
$anchor='LC_'.$anchor->id(); |
|
} else { |
|
$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" |
Line 691 sub getDescription {
|
Line 702 sub getDescription {
|
} |
} |
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') { |
return &Apache::lonhtmlcommon::direct_parm_link(&mt("Answer available"),$res->symb(),'answerdate,duedate',$part); |
my $msg = &mt('Answer available'); |
|
my $parmlist = 'answerdate,duedate'; |
|
if (($res->is_tool) && ($res->is_gradable())) { |
|
if (($status == $res->PARTIALLY_CORRECT) && ($res->parmval('retrypartial',$part))) { |
|
$msg = &mt('Grade received'); |
|
$parmlist = 'retrypartial'; |
|
} else { |
|
$msg = &mt('Grade available'); |
|
} |
|
} |
|
return &Apache::lonhtmlcommon::direct_parm_link($msg,$res->symb(),$parmlist,$part); |
} |
} |
if ($status == $res->EXCUSED) { |
if ($status == $res->EXCUSED) { |
return &mt("Excused by instructor"); |
return &mt("Excused by instructor"); |
Line 942 sub render_resource {
|
Line 963 sub render_resource {
|
$newBranchText = "<img src='$location/branch.gif' alt=".mt('Branch')." />"; |
$newBranchText = "<img src='$location/branch.gif' alt=".mt('Branch')." />"; |
} |
} |
|
|
# links to open and close the folder |
|
|
|
my $whitespace = $location.'/whitespace_21.gif'; |
my $whitespace = $location.'/whitespace_21.gif'; |
my ($nomodal,$linkopen,$linkclose); |
my ($nomodal,$linkopen,$linkclose); |
unless ($resource->is_map() || $params->{'resource_nolink'}) { |
unless ($resource->is_map() || $params->{'resource_nolink'}) { |
Line 997 sub render_resource {
|
Line 1016 sub render_resource {
|
if ($it->{CONDITION}) { |
if ($it->{CONDITION}) { |
$nowOpen = !$nowOpen; |
$nowOpen = !$nowOpen; |
} |
} |
my $folderType; |
|
if (&advancedUser() && $resource->is_missing_map()) { |
my $folderType = $resource->is_sequence() ? 'folder' : 'page'; |
$folderType = 'none'; |
|
} else { |
|
$folderType = $resource->is_sequence() ? 'folder' : 'page'; |
|
} |
|
my $title=$resource->title; |
my $title=$resource->title; |
$title=~s/\"/\&qout;/g; |
$title=~s/\"/\&qout;/g; |
if (!$params->{'resource_no_folder_link'}) { |
if (!$params->{'resource_no_folder_link'}) { |
Line 1035 sub render_resource {
|
Line 1050 sub render_resource {
|
} |
} |
} |
} |
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'}))) && |
(&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 1049 sub render_resource {
|
Line 1064 sub render_resource {
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
} elsif ($params->{'mapUnlisted'}) { |
} elsif ($params->{'mapUnlisted'}) { |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('unlisted').')</span> '; |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('unlisted').')</span> '; |
} elsif ($params->{'mapHiddenDeepLink'} || $resource->deeplinkout()) { |
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('not shown').')</span> '; |
|
} |
} |
} else { |
} else { |
if ($resource->randomout()) { |
if ($resource->randomout()) { |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('hidden').')</span> '; |
} elsif ($resource->deeplinkout()) { |
} elsif (($resource->deeplink($params->{caller}) eq 'absent') || |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('not shown').')</span> '; |
($resource->deeplink($params->{caller}) eq 'grades')) { |
} else { |
$nonLinkedText .= ' <span class="LC_warning">('.&mt('unlisted').')</span> '; |
my $deeplink = $resource->deeplink($params->{caller}); |
|
if ((($deeplink eq 'absent') || ($deeplink eq 'grades')) && |
|
&advancedUser()) { |
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('unlisted').')</span> '; |
|
} elsif (($deeplink) && ($deeplink) ne 'full') { |
|
if (&advancedUser()) { |
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('deep-link access'). |
|
')</span> '; |
|
} else { |
|
$nonLinkedText .= ' <span class="LC_warning">('.&mt('access via external site'). |
|
')</span> '; |
|
} |
|
} |
|
} |
} |
} |
} |
if (!$resource->condval()) { |
if (!$resource->condval()) { |
Line 1195 sub render_quick_status {
|
Line 1195 sub render_quick_status {
|
my $linkclose = "</a>"; |
my $linkclose = "</a>"; |
|
|
$result .= '<td class="LC_middle">'; |
$result .= '<td class="LC_middle">'; |
if ($resource->is_problem() && |
if ($resource->is_gradable() && |
!$firstDisplayed) { |
!$firstDisplayed) { |
my $icon = $statusIconMap{$resource->simpleStatus($part)}; |
my $icon = $statusIconMap{$resource->simpleStatus($part)}; |
my $alt = $iconAltTags{$icon}; |
my $alt = $iconAltTags{$icon}; |
Line 1220 sub render_long_status {
|
Line 1220 sub render_long_status {
|
|
|
my $color; |
my $color; |
my $info = ''; |
my $info = ''; |
if ($resource->is_problem() || $resource->is_practice()) { |
if ($resource->is_gradable() || $resource->is_practice()) { |
$color = $colormap{$resource->status}; |
$color = $colormap{$resource->status}; |
|
|
if (dueInLessThan24Hours($resource, $part)) { |
if (dueInLessThan24Hours($resource, $part)) { |
Line 1234 sub render_long_status {
|
Line 1234 sub render_long_status {
|
} |
} |
} |
} |
} |
} |
|
|
if ($resource->kind() eq "res" && |
if (($resource->kind() eq "res") && |
$resource->is_raw_problem() && |
($resource->is_raw_problem() || $resource->is_gradable()) && |
!$firstDisplayed) { |
!$firstDisplayed) { |
if ($color) {$result .= '<span style="color:'.$color.'"'.$info.'><b>'; } |
if ($color) {$result .= '<span style="color:'.$color.'"'.$info.'><b>'; } |
$result .= getDescription($resource, $part); |
$result .= getDescription($resource, $part); |
Line 1283 my @statuses = ($resObj->CORRECT, $resOb
|
Line 1283 my @statuses = ($resObj->CORRECT, $resOb
|
|
|
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_gradable() && !$resource->contains_problem) { return '<td></td>'; } |
if ($params->{showParts}) { |
if ($params->{showParts}) { |
return '<td></td>'; |
return '<td></td>'; |
} |
} |
Line 1394 sub render {
|
Line 1394 sub render {
|
# Without renaming the filterfunc, the server seems to go into |
# Without renaming the filterfunc, the server seems to go into |
# an infinite loop |
# an infinite loop |
my $oldFilterFunc = $filterFunc; |
my $oldFilterFunc = $filterFunc; |
$filterFunc = sub { my $res = shift; return !$res->randomout() && |
$filterFunc = sub { my $res = shift; return !$res->randomout() && |
($res->deeplink($args->{'caller'}) ne 'absent') && |
($res->deeplink($args->{'caller'}) ne 'absent') && |
($res->deeplink($args->{'caller'}) ne 'grades') && |
($res->deeplink($args->{'caller'}) ne 'grades') && |
!$res->deeplinkout() && |
|
&$oldFilterFunc($res);}; |
&$oldFilterFunc($res);}; |
} |
} |
|
|
my $condition = 0; |
my $condition = 0; |
if ($env{'form.condition'}) { |
if ($env{'form.condition'}) { |
$condition = 1; |
$condition = 1; |
} elsif (($env{'request.deeplink.login'}) && ($env{'request.course.id'}) && (!$userCanSeeHidden)) { |
|
if (!defined($navmap)) { |
|
$navmap = Apache::lonnavmaps::navmap->new(); |
|
} |
|
if (defined($navmap)) { |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $symb = &Apache::loncommon::symb_from_tinyurl($env{'request.deeplink.login'},$cnum,$cdom); |
|
if ($symb) { |
|
my $deeplink; |
|
my $res = $navmap->getBySymb($symb); |
|
if ($res->is_map()) { |
|
my $mapname = &Apache::lonnet::declutter($res->src()); |
|
$mapname = &Apache::lonnet::deversion($mapname); |
|
$deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink"); |
|
} else { |
|
$deeplink = $res->deeplink(); |
|
} |
|
if ($deeplink ne '') { |
|
if ((split(/,/,$deeplink))[1] eq 'hide') { |
|
if ($res->is_map()) { |
|
map { $filterHash->{$_} = 1 if $_ } split(/,/,$res->map_hierarchy()); |
|
} else { |
|
my $mapurl = (&Apache::lonnet::decode_symb($symb))[0]; |
|
my $map = $navmap->getResourceByUrl($mapurl); |
|
map { $filterHash->{$_} = 1 if $_ } split(/,/,$map->map_hierarchy()); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
} |
|
|
if (!$env{'form.folderManip'} && !defined($args->{'iterator'}) && !$args->{'nocurrloc'}) { |
if (!$env{'form.folderManip'} && !defined($args->{'iterator'})) { |
# 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(); |
Line 1458 sub render {
|
Line 1426 sub render {
|
my $currenturl = $env{'form.postdata'}; |
my $currenturl = $env{'form.postdata'}; |
#$currenturl=~s/^http\:\/\///; |
#$currenturl=~s/^http\:\/\///; |
#$currenturl=~s/^[^\/]+//; |
#$currenturl=~s/^[^\/]+//; |
unless ($args->{'caller'} eq 'sequence') { |
unless ($args->{'caller'} eq 'sequence') { |
$here = $jump = &Apache::lonnet::symbread($currenturl); |
$here = $jump = &Apache::lonnet::symbread($currenturl); |
} |
} |
} |
} |
if (($here eq '') && ($args->{'caller'} ne 'sequence')) { |
if (($here eq '') && ($args->{'caller'} ne 'sequence')) { |
my $last; |
my $last; |
if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', |
if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', |
&GDBM_READER(),0640)) { |
&GDBM_READER(),0640)) { |
Line 1476 sub render {
|
Line 1444 sub render {
|
my $mapIterator = $navmap->getIterator(undef, undef, undef, 1); |
my $mapIterator = $navmap->getIterator(undef, undef, undef, 1); |
my $curRes; |
my $curRes; |
my $found = 0; |
my $found = 0; |
my $here_is_navmaps = 0; |
|
if ($here =~ m{___\d+___adm/navmaps$}) { |
|
$here_is_navmaps = 1; |
|
} |
|
|
|
# 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 ($here && ($curRes = $mapIterator->next()) && !$found && !$here_is_navmaps) { |
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 1526 sub render {
|
Line 1490 sub render {
|
if ($args->{'iterator_map'}) { |
if ($args->{'iterator_map'}) { |
my $map = $args->{'iterator_map'}; |
my $map = $args->{'iterator_map'}; |
$map = $navmap->getResourceByUrl($map); |
$map = $navmap->getResourceByUrl($map); |
if (ref($map)) { |
my $firstResource = $map->map_start(); |
my $firstResource = $map->map_start(); |
my $finishResource = $map->map_finish(); |
my $finishResource = $map->map_finish(); |
|
$args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition); |
$args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition); |
} else { |
|
return; |
|
} |
|
} else { |
} else { |
$args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition,undef,$args->{'include_top_level_map'}); |
$args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition,undef,$args->{'include_top_level_map'}); |
} |
} |
Line 1601 sub render {
|
Line 1562 sub render {
|
'&here='.&escape($here); |
'&here='.&escape($here); |
$text='Open all folders'; |
$text='Open all folders'; |
} |
} |
|
if ($env{'form.register'}) { |
|
$link .= '&register='.$env{'form.register'}; |
|
} |
if ($args->{'caller'} eq 'navmapsdisplay') { |
if ($args->{'caller'} eq 'navmapsdisplay') { |
unless ($args->{'notools'}) { |
unless ($args->{'notools'}) { |
&add_linkitem($args->{'linkitems'},'changefolder', |
&add_linkitem($args->{'linkitems'},'changefolder', |
Line 1624 sub render {
|
Line 1588 sub render {
|
<input type="hidden" name="navurl" value="$querystr" /> |
<input type="hidden" name="navurl" value="$querystr" /> |
<input type="hidden" name="navtime" value="$time" /> |
<input type="hidden" name="navtime" value="$time" /> |
END |
END |
|
if ($env{'form.register'}) { |
|
$result .= '<input type="hidden" name="register" value="'.$env{'form.register'}.'" />'; |
|
} |
if ($args->{'sort'} eq 'discussion') { |
if ($args->{'sort'} eq 'discussion') { |
my $totdisc = 0; |
my $totdisc = 0; |
my $haveDisc = ''; |
my $haveDisc = ''; |
Line 1644 END
|
Line 1611 END
|
} |
} |
$result.='</form>'; |
$result.='</form>'; |
} |
} |
if (($args->{'caller'} eq 'navmapsdisplay') && ($env{'request.course.id'})) { |
if (($args->{'caller'} eq 'navmapsdisplay') && |
|
((&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 |
"uploaded/$cdom/$cnum/default.sequence") { |
"uploaded/$cdom/$cnum/default.sequence") { |
if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || |
&add_linkitem($args->{'linkitems'},'edittoplevel', |
(&Apache::lonnet::allowed('cev',$env{'request.course.id'}))) { |
"javascript:gocmd('/adm/coursedocs','editdocs');", |
&add_linkitem($args->{'linkitems'},'edittoplevel', |
'Content Editor'); |
"javascript:gocmd('/adm/coursedocs','editdocs');", |
|
'Content Editor'); |
|
} |
|
if ($counter) { |
|
&add_linkitem($args->{'linkitems'},'printout', |
|
"javascript:gopost('/adm/printout','/adm/navmaps');", |
|
'Prepare a printable document'); |
|
} |
|
} |
} |
} |
} |
|
|
Line 1702 END
|
Line 1663 END
|
# We also do this even if $args->{'suppressEmptySequences'} |
# We also do this even if $args->{'suppressEmptySequences'} |
# is not true, so we can hide empty sequences for which the |
# is not true, so we can hide empty sequences for which the |
# hiddenresource parameter is set to yes (at map level), or |
# hiddenresource parameter is set to yes (at map level), or |
# mark as hidden for users who have $userCanSeeHidden. |
# mark as hidden for users who have $userCanSeeHidden. |
# Use DFS for speed, since structure actually doesn't matter, |
# Use DFS for speed, since structure actually doesn't matter, |
# except what map has what resources. |
# except what map has what resources. |
# |
|
# To ensure the "Selected Resources from selected folder in course" |
|
# printout generation option will work in sessions launched via a |
|
# deep link, the value of $args->{'filterFunc'} included in the |
|
# call to lonnavmaps::render() is omitted from the filter function |
|
# used with the DFS Iterator when $args->{'caller'} is 'printout'. |
|
# |
|
# As a result $sequence->{DATA}->{HAS_VISIBLE_CHILDREN} can be |
|
# set to 1 for folder(s) which include resources only accessible |
|
# for sessions launched via a deep link, when the current session |
|
# is of that type. |
|
|
|
my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, |
my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, |
$it->{FIRST_RESOURCE}, |
$it->{FIRST_RESOURCE}, |
$it->{FINISH_RESOURCE}, |
$it->{FINISH_RESOURCE}, |
{}, undef, 1); |
{}, undef, 1); |
|
|
my $dfsFilterFunc; |
|
if ($args->{'caller'} eq 'printout') { |
|
$dfsFilterFunc = sub { my $res = shift; return !$res->randomout() && |
|
($res->deeplink($args->{'caller'}) ne 'absent') && |
|
($res->deeplink($args->{'caller'}) ne 'grades') && |
|
!$res->deeplinkout();}; |
|
} else { |
|
$dfsFilterFunc = $filterFunc; |
|
} |
|
my $depth = 0; |
my $depth = 0; |
$dfsit->next(); |
$dfsit->next(); |
my $curRes = $dfsit->next(); |
my $curRes = $dfsit->next(); |
Line 1738 END
|
Line 1678 END
|
if ($curRes == $dfsit->BEGIN_MAP()) { $depth++; } |
if ($curRes == $dfsit->BEGIN_MAP()) { $depth++; } |
if ($curRes == $dfsit->END_MAP()) { $depth--; } |
if ($curRes == $dfsit->END_MAP()) { $depth--; } |
|
|
if (ref($curRes)) { |
if (ref($curRes)) { |
# Parallel pre-processing: Do sequences have non-filtered-out children? |
# Parallel pre-processing: Do sequences have non-filtered-out children? |
if ($curRes->is_map()) { |
if ($curRes->is_map()) { |
$curRes->{DATA}->{HAS_VISIBLE_CHILDREN} = 0; |
$curRes->{DATA}->{HAS_VISIBLE_CHILDREN} = 0; |
Line 1749 END
|
Line 1689 END
|
} elsif ($curRes->src()) { |
} elsif ($curRes->src()) { |
# Not a sequence: if it's filtered, ignore it, otherwise |
# Not a sequence: if it's filtered, ignore it, otherwise |
# rise up the stack and mark the sequences as having children |
# rise up the stack and mark the sequences as having children |
if (&$dfsFilterFunc($curRes)) { |
if (&$filterFunc($curRes)) { |
for my $sequence (@{$dfsit->getStack()}) { |
for my $sequence (@{$dfsit->getStack()}) { |
next unless ($sequence->is_map()); |
|
$sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1; |
$sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1; |
} |
} |
} |
} |
Line 1875 END
|
Line 1814 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 |
$args->{'mapHidden'} = 0; |
$args->{'mapHidden'} = 0; |
$args->{'mapUnlisted'} = 0; |
$args->{'mapUnlisted'} = 0; |
$args->{'mapHiddenDeepLink'} = 0; |
|
if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) { |
if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) { |
if ($args->{'suppressEmptySequences'}) { |
if ($args->{'suppressEmptySequences'}) { |
next; |
next; |
} else { |
} else { |
my $mapname = &Apache::lonnet::declutter($curRes->src()); |
my $mapname = &Apache::lonnet::declutter($curRes->src()); |
$mapname = &Apache::lonnet::deversion($mapname); |
$mapname = &Apache::lonnet::deversion($mapname); |
if (lc($navmap->get_mapparam(undef,$mapname,"0.hiddenresource")) eq 'yes') { |
if (lc($navmap->get_mapparam(undef,$mapname,"0.hiddenresource")) eq 'yes') { |
if ($userCanSeeHidden) { |
if ($userCanSeeHidden) { |
$args->{'mapHidden'} = 1; |
$args->{'mapHidden'} = 1; |
} else { |
} else { |
next; |
next; |
} |
} |
} elsif ($curRes->deeplinkout) { |
|
if ($userCanSeeHidden) { |
|
$args->{'mapHiddenDeepLink'} = 1; |
|
} else { |
|
next; |
|
} |
|
} else { |
} else { |
my $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink"); |
my $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink"); |
my ($state,$others,$listed) = split(/,/,$deeplink); |
if (($deeplink eq 'absent') || ($deeplink eq 'grades')) { |
if (($listed eq 'absent') || ($listed eq 'grades')) { |
|
if ($userCanSeeHidden) { |
if ($userCanSeeHidden) { |
$args->{'mapUnlisted'} = 1; |
$args->{'mapUnlisted'} = 1; |
} else { |
} else { |
Line 1968 END
|
Line 1899 END
|
} |
} |
} |
} |
# If deep-link parameter is set (and is not set to full) suppress link |
# If deep-link parameter is set (and is not set to full) suppress link |
# unless privileged user, tinyurl used for login resolved to a map, and |
# unless priviliged user, or calling context is sequence, and parameter |
# the resource is within the map. |
# set at map level |
if ((!$curRes->deeplink($args->{'caller'})) || |
if ((!$curRes->deeplink($args->{'caller'})) || |
($curRes->deeplink($args->{'caller'}) eq 'full') || &advancedUser()) { |
($curRes->deeplink($args->{'caller'}) eq 'full') || &advancedUser()) { |
$args->{'resource_nolink'} = 0; |
$args->{'resource_nolink'} = 0; |
} else { |
} else { |
$args->{'resource_nolink'} = 1; |
$args->{'resource_nolink'} = 1; |
} |
} |
|
|
# If the multipart problem was condensed, "forget" it was multipart |
# If the multipart problem was condensed, "forget" it was multipart |
if (scalar(@parts) == 1) { |
if (scalar(@parts) == 1) { |
$args->{'multipart'} = 0; |
$args->{'multipart'} = 0; |
Line 2002 END
|
Line 1933 END
|
if ($env{'request.course.id'}) { |
if ($env{'request.course.id'}) { |
if (($is_ssl) && ($src =~ m{^\Q/public/$cdom/$cnum/syllabus\E($|\?)}) && |
if (($is_ssl) && ($src =~ m{^\Q/public/$cdom/$cnum/syllabus\E($|\?)}) && |
($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { |
($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { |
unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { |
unless (&Apache::lonnet::uses_sts()) { |
if ($hostname ne '') { |
if ($hostname ne '') { |
$src = 'http://'.$hostname.$src; |
$src = 'http://'.$hostname.$src; |
} |
} |
$src .= ($srcHasQuestion? '&' : '?') . 'usehttp=1'; |
$src .= ($srcHasQuestion? '&' : '?') . 'usehttp=1'; |
$srcHasQuestion = 1; |
$srcHasQuestion = 1;a |
} |
} |
} elsif (($is_ssl) && ($src =~ m{^\Q/adm/wrapper/ext/\E(?!https:)})) { |
} elsif (($is_ssl) && ($src =~ m{^\Q/adm/wrapper/ext/\E(?!https:)})) { |
unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { |
unless (&Apache::lonnet::uses_sts()) { |
if ($hostname ne '') { |
if ($hostname ne '') { |
$src = 'http://'.$hostname.$src; |
$src = 'http://'.$hostname.$src; |
} |
} |
Line 2020 END
|
Line 1951 END
|
} |
} |
} |
} |
if (defined($anchor)) { $anchor='#'.$anchor; } |
if (defined($anchor)) { $anchor='#'.$anchor; } |
if (($args->{'caller'} eq 'sequence') && ($curRes->is_map())) { |
if (($args->{'caller'} eq 'sequence') && ($curRes->is_map())) { |
$args->{"resourceLink"} = $src.($srcHasQuestion?'&':'?') .'navmap=1'; |
$args->{"resourceLink"} = $src.($srcHasQuestion?'&':'?') .'navmap=1'; |
} else { |
} else { |
$args->{"resourceLink"} = $src. |
$args->{"resourceLink"} = $src. |
($srcHasQuestion?'&':'?') . |
($srcHasQuestion?'&':'?') . |
'symb=' . &escape($symb).$inhibitmenu.$anchor; |
'symb=' . &escape($symb).$inhibitmenu.$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 2054 END
|
Line 1985 END
|
$currentJumpDelta) { |
$currentJumpDelta) { |
# Jam the anchor after the <td> tag; |
# Jam the anchor after the <td> tag; |
# necessary for valid HTML (which Mozilla requires) |
# necessary for valid HTML (which Mozilla requires) |
$colHTML =~ s/\>/\>\<a name="curloc" \>\<\/a\>/; |
$colHTML =~ s/\>/\>\<a name="curloc" \/\>/; |
$displayedJumpMarker = 1; |
$displayedJumpMarker = 1; |
} |
} |
$result .= $colHTML . "\n"; |
$result .= $colHTML . "\n"; |
Line 2128 sub show_linkitems_toolbar {
|
Line 2059 sub show_linkitems_toolbar {
|
$result .= '<td align="left">'."\n". |
$result .= '<td align="left">'."\n". |
'<ul id="LC_toolbar">'; |
'<ul id="LC_toolbar">'; |
my @linkorder = ('firsthomework','everything','uncompleted', |
my @linkorder = ('firsthomework','everything','uncompleted', |
'changefolder','clearbubbles','printout','edittoplevel'); |
'changefolder','clearbubbles','edittoplevel'); |
foreach my $link (@linkorder) { |
foreach my $link (@linkorder) { |
if (ref($args->{'linkitems'}{$link}) eq 'HASH') { |
if (ref($args->{'linkitems'}{$link}) eq 'HASH') { |
if ($args->{'linkitems'}{$link}{'text'} ne '') { |
if ($args->{'linkitems'}{$link}{'text'} ne '') { |
Line 2347 sub change_user {
|
Line 2278 sub change_user {
|
|
|
|
|
|
|
# Now clear the parm cache and reconstruct the parm hash fromt he big_hash |
# Now clear the parm cache and reconstruct the parm hash from the big_hash |
# param.xxxx keys. |
# param.xxxx keys. |
|
|
$self->{PARM_CACHE} = {}; |
$self->{PARM_CACHE} = {}; |
Line 2541 sub getIterator {
|
Line 2472 sub getIterator {
|
my $self = shift; |
my $self = shift; |
my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift, |
my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift, |
shift, undef, shift, |
shift, undef, shift, |
shift, shift, shift); |
shift, shift); |
return $iterator; |
return $iterator; |
} |
} |
|
|
Line 2812 sub parmval {
|
Line 2743 sub parmval {
|
return $self->{PARM_CACHE}->{$hashkey}; |
return $self->{PARM_CACHE}->{$hashkey}; |
} |
} |
} |
} |
|
|
my $result = $self->parmval_real($what, $symb, $recurse); |
my $result = $self->parmval_real($what, $symb, $recurse); |
$self->{PARM_CACHE}->{$hashkey} = $result; |
$self->{PARM_CACHE}->{$hashkey} = $result; |
if (wantarray) { |
if (wantarray) { |
Line 2845 sub parmval_real {
|
Line 2777 sub parmval_real {
|
|
|
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); |
$mapname = &Apache::lonnet::deversion($mapname); |
$mapname = &Apache::lonnet::deversion($mapname); |
|
my $toolsymb = ''; |
|
if ($fn =~ /ext\.tool$/) { |
|
$toolsymb = $symb; |
|
} |
|
my ($recursed,@recurseup); |
|
|
# ----------------------------------------------------- Cascading lookup scheme |
# ----------------------------------------------------- Cascading lookup scheme |
my $rwhat=$what; |
my $rwhat=$what; |
$what=~s/^parameter\_//; |
$what=~s/^parameter\_//; |
$what=~s/\_/\./; |
$what=~s/\_/\./; |
|
|
my $symbparm=$symb.'.'.$what; |
my $symbparm=$symb.'.'.$what; |
|
my $recurseparm=$mapname.'___(rec).'.$what; |
my $mapparm=$mapname.'___(all).'.$what; |
my $mapparm=$mapname.'___(all).'.$what; |
my $usercourseprefix=$cid; |
my $usercourseprefix=$cid; |
|
|
|
|
|
|
my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what; |
my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what; |
my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm; |
my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm; |
|
my $grpleveli=$usercourseprefix.'.['.$cgroup.'].'.$recurseparm; |
my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm; |
my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm; |
|
|
|
|
my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what; |
my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what; |
my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm; |
my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm; |
|
my $secleveli=$usercourseprefix.'.['.$csec.'].'.$recurseparm; |
my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm; |
my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm; |
|
|
|
|
my $courselevel= $usercourseprefix.'.'.$what; |
my $courselevel= $usercourseprefix.'.'.$what; |
my $courselevelr=$usercourseprefix.'.'.$symbparm; |
my $courselevelr=$usercourseprefix.'.'.$symbparm; |
|
my $courseleveli=$usercourseprefix.'.'.$recurseparm; |
my $courselevelm=$usercourseprefix.'.'.$mapparm; |
my $courselevelm=$usercourseprefix.'.'.$mapparm; |
|
|
|
|
Line 2879 sub parmval_real {
|
Line 2821 sub parmval_real {
|
if ($uname and defined($useropt)) { |
if ($uname and defined($useropt)) { |
if (defined($$useropt{$courselevelr})) { return [$$useropt{$courselevelr},'resource']; } |
if (defined($$useropt{$courselevelr})) { return [$$useropt{$courselevelr},'resource']; } |
if (defined($$useropt{$courselevelm})) { return [$$useropt{$courselevelm},'map']; } |
if (defined($$useropt{$courselevelm})) { return [$$useropt{$courselevelm},'map']; } |
|
if (defined($$useropt{$courseleveli})) { return [$$useropt{$courseleveli},'map']; } |
|
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},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
|
if (defined($$useropt{$recursechk})) { return [$$useropt{$recursechk},'map']; } |
|
} |
if (defined($$useropt{$courselevel})) { return [$$useropt{$courselevel},'course']; } |
if (defined($$useropt{$courselevel})) { return [$$useropt{$courselevel},'course']; } |
} |
} |
|
|
Line 2886 sub parmval_real {
|
Line 2845 sub parmval_real {
|
if ($cgroup ne '' and defined($courseopt)) { |
if ($cgroup ne '' and defined($courseopt)) { |
if (defined($$courseopt{$grplevelr})) { return [$$courseopt{$grplevelr},'resource']; } |
if (defined($$courseopt{$grplevelr})) { return [$$courseopt{$grplevelr},'resource']; } |
if (defined($$courseopt{$grplevelm})) { return [$$courseopt{$grplevelm},'map']; } |
if (defined($$courseopt{$grplevelm})) { return [$$courseopt{$grplevelm},'map']; } |
|
if (defined($$courseopt{$grpleveli})) { return [$$courseopt{$grpleveli},'map']; } |
|
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},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(rec).'.$what; |
|
if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; } |
|
} |
if (defined($$courseopt{$grplevel})) { return [$$courseopt{$grplevel},'course']; } |
if (defined($$courseopt{$grplevel})) { return [$$courseopt{$grplevel},'course']; } |
} |
} |
|
|
if ($csec and defined($courseopt)) { |
if ($csec ne '' and defined($courseopt)) { |
if (defined($$courseopt{$seclevelr})) { return [$$courseopt{$seclevelr},'resource']; } |
if (defined($$courseopt{$seclevelr})) { return [$$courseopt{$seclevelr},'resource']; } |
if (defined($$courseopt{$seclevelm})) { return [$$courseopt{$seclevelm},'map']; } |
if (defined($$courseopt{$seclevelm})) { return [$$courseopt{$seclevelm},'map']; } |
|
if (defined($$courseopt{$secleveli})) { return [$$courseopt{$secleveli},'map']; } |
|
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},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what; |
|
if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; } |
|
} |
if (defined($$courseopt{$seclevel})) { return [$$courseopt{$seclevel},'course']; } |
if (defined($$courseopt{$seclevel})) { return [$$courseopt{$seclevel},'course']; } |
} |
} |
|
|
Line 2908 sub parmval_real {
|
Line 2901 sub parmval_real {
|
|
|
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,$toolsymb); |
if (defined($default)) { return [$default,'resource']} |
if (defined($default)) { return [$default,'resource']} |
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat); |
$default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat,$toolsymb); |
if (defined($default)) { return [$default,'resource']} |
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},'map']; } |
if (defined($$courseopt{$courselevelm})) { return [$$courseopt{$courselevelm},'map']; } |
|
if (defined($$courseopt{$courseleveli})) { return [$$courseopt{$courseleveli},'map']; } |
|
unless ($recursed) { |
|
@recurseup = $self->recurseup_maps($mapname); |
|
$recursed = 1; |
|
} |
|
foreach my $item (@recurseup) { |
|
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
|
if (defined($$courseopt{$norecursechk})) { |
|
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
|
return [$$courseopt{$norecursechk},'map']; |
|
} else { |
|
last; |
|
} |
|
} |
|
my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what; |
|
if (defined($$courseopt{$recursechk})) { |
|
return [$$courseopt{$recursechk},'map']; |
|
} |
|
} |
if (defined($$courseopt{$courselevel})) { |
if (defined($$courseopt{$courselevel})) { |
my $ret = [$$courseopt{$courselevel},'course']; |
my $ret = [$$courseopt{$courselevel},'course']; |
return $ret; |
return $ret; |
Line 2933 sub parmval_real {
|
Line 2945 sub parmval_real {
|
if (defined($partgeneral[0])) { return \@partgeneral; } |
if (defined($partgeneral[0])) { return \@partgeneral; } |
} |
} |
if ($recurse) { return []; } |
if ($recurse) { return []; } |
my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat); |
my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat,$toolsymb); |
if (defined($pack_def)) { return [$pack_def,'resource']; } |
if (defined($pack_def)) { return [$pack_def,'resource']; } |
return ['']; |
return ['']; |
} |
} |
Line 2979 sub recursed_crumbs {
|
Line 2991 sub recursed_crumbs {
|
my $pc = $map->map_pc(); |
my $pc = $map->map_pc(); |
next if ((!$pc) || ($pc == 1)); |
next if ((!$pc) || ($pc == 1)); |
push(@links,$map); |
push(@links,$map); |
my $text = $map->title(); |
push(@revmapinfo,{'href' => $map->link().'?navmap=1','text' => $map->title(),'no_mt' => 1,}); |
if ($text eq '') { |
$totallength += length($map->title()); |
$text = '...'; |
|
} |
|
push(@revmapinfo,{'href' => $env{'request.use_absolute'}.$map->link().'?navmap=1','text' => $text,'no_mt' => 1,}); |
|
$totallength += length($text); |
|
} |
} |
my $numlinks = scalar(@links); |
my $numlinks = scalar(@links); |
if ($numlinks) { |
if ($numlinks) { |
Line 2996 sub recursed_crumbs {
|
Line 3004 sub recursed_crumbs {
|
} |
} |
@revmapinfo = (); |
@revmapinfo = (); |
foreach my $map (@links) { |
foreach my $map (@links) { |
my $title = $map->title(); |
my $showntitle = &truncate_crumb_text($map->title(),$avg); |
if ($title eq '') { |
|
$title = '...'; |
|
} |
|
my $showntitle = &truncate_crumb_text($title,$avg); |
|
if ($showntitle ne '') { |
if ($showntitle ne '') { |
push(@revmapinfo,{'href' => $env{'request.use_absolute'}.$map->link().'?navmap=1','text' => $showntitle,'no_mt' => 1,}); |
push(@revmapinfo,{'href' => $map->link().'?navmap=1','text' => $showntitle,'no_mt' => 1,}); |
} |
} |
} |
} |
} |
} |
Line 3059 sub map_printdates {
|
Line 3063 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); |
Line 3089 sub get_mapparam {
|
Line 3093 sub get_mapparam {
|
my $result=''; |
my $result=''; |
my ($recursed,@recurseup); |
my ($recursed,@recurseup); |
|
|
|
|
# Figure out which map we are in. |
# Figure out which map we are in. |
|
|
if ($symb && !$mapname) { |
if ($symb && !$mapname) { |
Line 3097 sub get_mapparam {
|
Line 3102 sub get_mapparam {
|
$mapname = &Apache::lonnet::deversion($mapname); |
$mapname = &Apache::lonnet::deversion($mapname); |
} |
} |
|
|
|
|
my $rwhat=$what; |
my $rwhat=$what; |
$what=~s/^parameter\_//; |
$what=~s/^parameter\_//; |
$what=~s/\_/\./; |
$what=~s/\_/\./; |
|
|
# 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 $usercourseprefix=$cid; |
my $usercourseprefix=$cid; |
|
|
|
|
my $grplevel = "$usercourseprefix.[$cgroup].$mapparm"; |
my $grplevelm = "$usercourseprefix.[$cgroup].$mapparm"; |
my $seclevel = "$usercourseprefix.[$csec].$mapparm"; |
my $seclevelm = "$usercourseprefix.[$csec].$mapparm"; |
my $courselevel = "$usercourseprefix.$mapparm"; |
my $courselevelm = "$usercourseprefix.$mapparm"; |
|
|
|
my $grpleveli = "$usercourseprefix.[$cgroup].$recurseparm"; |
|
my $secleveli = "$usercourseprefix.[$csec].$recurseparm"; |
|
my $courseleveli = "$usercourseprefix.$recurseparm"; |
|
|
# Get handy references to the hashes we need in $self: |
# Get handy references to the hashes we need in $self: |
|
|
Line 3124 sub get_mapparam {
|
Line 3133 sub get_mapparam {
|
|
|
|
|
if ($uname and defined($useropt)) { |
if ($uname and defined($useropt)) { |
if (defined($$useropt{$courselevel})) { |
if (defined($$useropt{$courselevelm})) { |
return $$useropt{$courselevel}; |
return $$useropt{$courselevelm}; |
} |
} |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
if (defined($$useropt{$courseleveli})) { |
unless ($recursed) { |
return $$useropt{$courseleveli}; |
@recurseup = $self->recurseup_maps($mapname); |
} |
$recursed = 1; |
unless ($recursed) { |
} |
@recurseup = $self->recurseup_maps($mapname); |
foreach my $item (@recurseup) { |
$recursed = 1; |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
} |
if (defined($$useropt{$norecursechk})) { |
foreach my $item (@recurseup) { |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
return $$useropt{$norecursechk}; |
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}; |
|
} |
} |
} |
} |
} |
|
|
Line 3148 sub get_mapparam {
|
Line 3164 sub get_mapparam {
|
|
|
|
|
if ($cgroup ne '' and defined ($courseopt)) { |
if ($cgroup ne '' and defined ($courseopt)) { |
if (defined($$courseopt{$grplevel})) { |
if (defined($$courseopt{$grplevelm})) { |
return $$courseopt{$grplevel}; |
return $$courseopt{$grplevelm}; |
} |
} |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
if (defined($$courseopt{$grpleveli})) { |
unless ($recursed) { |
return $$courseopt{$grpleveli}; |
@recurseup = $self->recurseup_maps($mapname); |
} |
$recursed = 1; |
unless ($recursed) { |
} |
@recurseup = $self->recurseup_maps($mapname); |
foreach my $item (@recurseup) { |
$recursed = 1; |
my $norecursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(all).'.$what; |
} |
if (defined($$courseopt{$norecursechk})) { |
foreach my $item (@recurseup) { |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
my $norecursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(all).'.$what; |
return $$courseopt{$norecursechk}; |
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 ne '' and defined($courseopt)) { |
|
if (defined($$courseopt{$seclevelm})) { |
|
return $$courseopt{$seclevelm}; |
if ($csec and defined($courseopt)) { |
|
if (defined($$courseopt{$seclevel})) { |
|
return $$courseopt{$seclevel}; |
|
} |
} |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
if (defined($$courseopt{$secleveli})) { |
unless ($recursed) { |
return $$courseopt{$secleveli}; |
@recurseup = $self->recurseup_maps($mapname); |
} |
$recursed = 1; |
unless ($recursed) { |
} |
@recurseup = $self->recurseup_maps($mapname); |
foreach my $item (@recurseup) { |
$recursed = 1; |
my $norecursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(all).'.$what; |
} |
if (defined($$courseopt{$norecursechk})) { |
foreach my $item (@recurseup) { |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
my $norecursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(all).'.$what; |
return $$courseopt{$norecursechk}; |
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: |
Line 3198 sub get_mapparam {
|
Line 3225 sub get_mapparam {
|
my $symbparm=$symb.'.'.$what; |
my $symbparm=$symb.'.'.$what; |
my $thisparm = $$parmhash{$symbparm}; |
my $thisparm = $$parmhash{$symbparm}; |
if (defined($thisparm)) { |
if (defined($thisparm)) { |
return $thisparm; |
return $thisparm; |
} |
} |
} |
} |
|
|
Line 3206 sub get_mapparam {
|
Line 3233 sub get_mapparam {
|
# Additional course parameters: |
# Additional course parameters: |
|
|
if (defined($courseopt)) { |
if (defined($courseopt)) { |
if (defined($$courseopt{$courselevel})) { |
if (defined($$courseopt{$courselevelm})) { |
return $$courseopt{$courselevel}; |
return $$courseopt{$courselevelm}; |
} |
} |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
unless ($recursed) { |
unless ($recursed) { |
@recurseup = $self->recurseup_maps($mapname); |
@recurseup = $self->recurseup_maps($mapname); |
$recursed = 1; |
$recursed = 1; |
} |
} |
if (@recurseup) { |
foreach my $item (@recurseup) { |
foreach my $item (@recurseup) { |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what; |
if (defined($$courseopt{$norecursechk})) { |
if (defined($$courseopt{$norecursechk})) { |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
if ($what =~ /\.(encrypturl|hiddenresource)$/) { |
return $$courseopt{$norecursechk}; |
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 3266 sub getcourseparam {
|
Line 3299 sub getcourseparam {
|
$what=~s/^parameter\_//; |
$what=~s/^parameter\_//; |
$what=~s/\_/\./; |
$what=~s/\_/\./; |
|
|
|
|
my $symbparm = $symb . '.' . $what; |
|
my $mapparm=$mapname.'___(all).'.$what; |
|
|
|
# Local refs to the hashes we're going to look at: |
# Local refs to the hashes we're going to look at: |
|
|
my $useropt = $self->{USER_OPT}; |
my $useropt = $self->{USER_OPT}; |
Line 3485 sub usedVersion {
|
Line 3514 sub usedVersion {
|
return $self->navhash("version_$linkurl"); |
return $self->navhash("version_$linkurl"); |
} |
} |
|
|
|
sub isFirstResource { |
|
my $self = shift; |
|
my $map = shift; |
|
my $symb = shift; |
|
return unless (ref($map)); |
|
my $isfirst; |
|
my $firstResource = $map->map_start(); |
|
if (ref($firstResource)) { |
|
if ((!$firstResource->is_map()) && ($firstResource->src() ne '')) { |
|
if ($firstResource->symb() eq $symb) { |
|
$isfirst = 1; |
|
} else { |
|
$isfirst = 0; |
|
} |
|
} else { |
|
my $it = $self->getIterator($firstResource,undef,undef,1); |
|
while ( my $res=$it->next()) { |
|
if ((ref($res)) && ($res->src() ne '') && (!$res->is_map())) { |
|
if ($res->symb() eq $symb) { |
|
$isfirst = 1; |
|
} else { |
|
$isfirst = 0; |
|
} |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
return $isfirst; |
|
} |
|
|
|
sub isLastResource { |
|
my $self = shift; |
|
my $map = shift; |
|
my $symb = shift; |
|
return unless (ref($map)); |
|
my $islast; |
|
my $lastResource = $map->map_finish(); |
|
if (ref($lastResource)) { |
|
if ((!$lastResource->is_map()) && ($lastResource->src() ne '')) { |
|
if ($lastResource->symb() eq $symb) { |
|
$islast = 1; |
|
} else { |
|
$islast = 0; |
|
} |
|
} else { |
|
my $currRes = $self->getBySymb($symb); |
|
if (ref($currRes)) { |
|
my $it = $self->getIterator($currRes,undef,undef,1); |
|
while ( my $res=$it->next()) { |
|
if ((ref($res)) && ($res->src() ne '') && (!$res->is_map())) { |
|
if ($res->symb() eq $symb) { |
|
$islast = 1; |
|
} else { |
|
$islast = 0; |
|
} |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return $islast; |
|
} |
|
|
1; |
1; |
|
|
package Apache::lonnavmaps::iterator; |
package Apache::lonnavmaps::iterator; |
Line 3515 getIterator behaves as follows:
|
Line 3609 getIterator behaves as follows:
|
|
|
=over 4 |
=over 4 |
|
|
=item * B<getIterator>(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap, $deeplinklisted): |
=item * B<getIterator>(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap): |
|
|
All parameters are optional. firstResource is a resource reference |
All parameters are optional. firstResource is a resource reference |
corresponding to where the iterator should start. It defaults to |
corresponding to where the iterator should start. It defaults to |
Line 3532 that is not just a single, 'redirecting'
|
Line 3626 that is not just a single, 'redirecting'
|
will return all information, starting with the top-level map, |
will return all information, starting with the top-level map, |
regardless of content. returnTopMap, if true (default false), will |
regardless of content. returnTopMap, if true (default false), will |
cause the iterator to return the top-level map object (resource 0.0) |
cause the iterator to return the top-level map object (resource 0.0) |
before anything else. deeplinklisted if true (default false), will |
before anything else. |
check "listed" status of a resource with a deeplink, and unless "absent" |
|
will exclude deeplink checking when retrieving the browsePriv from |
|
lonnet::allowed(). |
|
|
|
Thus, by default, only top-level resources will be shown. Change the |
Thus, by default, only top-level resources will be shown. Change the |
condition to a 1 without changing the hash, and all resources will be |
condition to a 1 without changing the hash, and all resources will be |
Line 3672 sub new {
|
Line 3763 sub new {
|
# have we done that yet? |
# have we done that yet? |
$self->{HAVE_RETURNED_0} = 0; |
$self->{HAVE_RETURNED_0} = 0; |
|
|
# Do we want to check the "listed" status for a resource for which |
|
# deeplinking applies. |
|
$self->{DEEPLINKLISTED} = shift; |
|
|
|
# Now, we need to pre-process the map, by walking forward and backward |
# Now, we need to pre-process the map, by walking forward and backward |
# over the parts of the map we're going to look at. |
# over the parts of the map we're going to look at. |
|
|
Line 3767 sub new {
|
Line 3854 sub new {
|
$finishResource, $self->{FILTER}, |
$finishResource, $self->{FILTER}, |
$self->{ALREADY_SEEN}, |
$self->{ALREADY_SEEN}, |
$self->{CONDITION}, |
$self->{CONDITION}, |
$self->{FORCE_TOP}, |
$self->{FORCE_TOP}); |
undef,$self->{DEEPLINKLISTED}); |
|
} |
} |
|
|
# Set up some bookkeeping information. |
# Set up some bookkeeping information. |
Line 3928 sub next {
|
Line 4014 sub next {
|
# That ends the main iterator logic. Now, do we want to recurse |
# That ends the main iterator logic. Now, do we want to recurse |
# down this map (if this resource is a map)? |
# down this map (if this resource is a map)? |
if ( ($self->{HERE}->is_sequence() || (!$closeAllPages && $self->{HERE}->is_page())) && |
if ( ($self->{HERE}->is_sequence() || (!$closeAllPages && $self->{HERE}->is_page())) && |
(defined($self->{FILTER}->{$self->{HERE}->map_pc()}) xor $self->{CONDITION}) && |
(defined($self->{FILTER}->{$self->{HERE}->map_pc()}) xor $self->{CONDITION})) { |
($env{'request.role.adv'} || !$self->{HERE}->randomout())) { |
|
$self->{RECURSIVE_ITERATOR_FLAG} = 1; |
$self->{RECURSIVE_ITERATOR_FLAG} = 1; |
my $firstResource = $self->{HERE}->map_start(); |
my $firstResource = $self->{HERE}->map_start(); |
my $finishResource = $self->{HERE}->map_finish(); |
my $finishResource = $self->{HERE}->map_finish(); |
Line 3938 sub next {
|
Line 4023 sub next {
|
$finishResource, $self->{FILTER}, |
$finishResource, $self->{FILTER}, |
$self->{ALREADY_SEEN}, |
$self->{ALREADY_SEEN}, |
$self->{CONDITION}, |
$self->{CONDITION}, |
$self->{FORCE_TOP}, |
$self->{FORCE_TOP}); |
undef,$self->{DEEPLINKLISTED}); |
|
} |
} |
|
|
# If this is a blank resource, don't actually return it. |
# If this is a blank resource, don't actually return it. |
# Should you ever find you need it, make sure to add an option to the code |
# Should you ever find you need it, make sure to add an option to the code |
# that you can use; other things depend on this behavior. |
# that you can use; other things depend on this behavior. |
my $browsePriv = $self->{HERE}->browsePriv($noblockcheck,$self->{DEEPLINKLISTED}); |
my $browsePriv = $self->{HERE}->browsePriv($noblockcheck); |
if (!$self->{HERE}->src() || |
if (!$self->{HERE}->src() || |
(!($browsePriv eq 'F') && !($browsePriv eq '2')) ) { |
(!($browsePriv eq 'F') && !($browsePriv eq '2')) ) { |
return $self->next($closeAllPages); |
return $self->next($closeAllPages); |
Line 4282 sub new {
|
Line 4366 sub new {
|
|
|
# This is a speed optimization, to avoid calling symb() too often. |
# This is a speed optimization, to avoid calling symb() too often. |
$self->{SYMB} = $self->symb(); |
$self->{SYMB} = $self->symb(); |
|
|
return $self; |
return $self; |
} |
} |
|
|
Line 4373 sub from { my $self=shift; return $self-
|
Line 4457 sub from { my $self=shift; return $self-
|
sub goesto { my $self=shift; return $self->navHash("goesto_", 1); } |
sub goesto { my $self=shift; return $self->navHash("goesto_", 1); } |
sub kind { my $self=shift; return $self->navHash("kind_", 1); } |
sub kind { my $self=shift; return $self->navHash("kind_", 1); } |
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); } |
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); } |
sub deeplinkout { my $self=shift; return $self->navHash("deeplinkout_", 1); } |
|
sub randompick { |
sub randompick { |
my $self = shift; |
my $self = shift; |
my $randompick = $self->parmval('randompick'); |
my $randompick = $self->parmval('randompick'); |
Line 4409 sub enclosing_map_src {
|
Line 4492 sub enclosing_map_src {
|
} |
} |
sub symb { |
sub symb { |
my $self=shift; |
my $self=shift; |
if (defined($self->{SYMB})) { return $self->{SYMB}; } |
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 4542 sub is_problem {
|
Line 4625 sub is_problem {
|
} |
} |
return 0; |
return 0; |
} |
} |
|
sub is_tool { |
|
my $self=shift; |
|
my $src = $self->src(); |
|
return ($src =~ /ext\.tool$/); |
|
} |
|
sub is_gradable { |
|
my $self=shift; |
|
my $src = $self->src(); |
|
if (($src =~ /$LONCAPA::assess_re/) || |
|
(($self->is_tool()) && ($self->parmval('gradable',0) =~ /^yes$/i))) { |
|
return !($self->is_practice()); |
|
} |
|
} |
# |
# |
# The has below is the set of status that are considered 'incomplete' |
# The has below is the set of status that are considered 'incomplete' |
# |
# |
Line 4600 sub is_sequence {
|
Line 4696 sub is_sequence {
|
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'; |
} |
} |
sub is_missing_map { |
|
my $self=shift; |
|
return $self->navHash("is_map_", 1) && |
|
$self->navHash("map_type_" . $self->map_pc()) eq 'none'; |
|
} |
|
sub is_survey { |
sub is_survey { |
my $self = shift(); |
my $self = shift(); |
my $part = shift(); |
my $part = shift(); |
Line 4954 sub duedate {
|
Line 5045 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 $timelimit = $1; |
my $timelimit = $1; |
my $first_access=&Apache::lonnet::get_first_access($interval[1], |
my $first_access=&Apache::lonnet::get_first_access($interval[1], |
$self->{SYMB}); |
$self->{SYMB}); |
if (defined($first_access)) { |
if (defined($first_access)) { |
my $interval = $first_access+$timelimit; |
my $interval = $first_access+$timelimit; |
$date = (!$due_date || $interval < $due_date) ? $interval |
$date = (!$due_date || $interval < $due_date) ? $interval |
Line 5054 sub slot_control {
|
Line 5145 sub slot_control {
|
return ($useslots,$availablestudent,$available); |
return ($useslots,$availablestudent,$available); |
} |
} |
sub deeplink { |
sub deeplink { |
my ($self,$caller,$action) = @_; |
my ($self,$caller) = @_; |
my $deeplink = $self->parmval("deeplink"); |
if ($caller eq 'sequence') { |
if ($deeplink) { |
my @deeplink = $self->parmval("deeplink"); |
my ($state,$others,$listed,$scope) = split(/,/,$deeplink); |
if ($deeplink[1] eq 'resource') { |
if ($action eq 'getlisted') { |
return $deeplink[0]; |
return $listed; |
|
} |
|
if ($env{'request.deeplink.login'}) { |
|
my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; |
|
my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; |
|
my $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom); |
|
if ($deeplink_symb) { |
|
my ($loginmap,$mapname); |
|
if ($deeplink_symb =~ /\.(page|sequence)$/) { |
|
$mapname = $self->enclosing_map_src(); |
|
$loginmap = &Apache::lonnet::clutter((&Apache::lonnet::decode_symb($deeplink_symb))[2]); |
|
return if ($mapname eq $loginmap); |
|
} else { |
|
return if ($deeplink_symb eq $self->symb()); |
|
if (($scope eq 'map') || ($scope eq 'rec')) { |
|
$mapname = $self->enclosing_map_src(); |
|
$loginmap = &Apache::lonnet::clutter((&Apache::lonnet::decode_symb($deeplink_symb))[0]); |
|
return if ($mapname eq $loginmap); |
|
} |
|
} |
|
if ($scope eq 'rec') { |
|
my $map_pc = $self->navHash('map_pc_'.$mapname); |
|
my @recurseup = split(/,/,$self->navHash('map_hierarchy_'.$map_pc)); |
|
my $login_pc = $self->navHash('map_pc_'.$loginmap); |
|
return if (grep(/^\Q$login_pc\E$/,@recurseup)); |
|
} |
|
} |
|
} |
|
unless (($caller eq 'sequence') || ($state eq 'both')) { |
|
return $listed; |
|
} |
} |
|
} else { |
|
return $self->parmval("deeplink"); |
} |
} |
return; |
|
} |
} |
|
|
# Multiple things need this |
# Multiple things need this |
Line 5099 sub getReturnHash {
|
Line 5161 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 5241 sub parts {
|
Line 5309 sub parts {
|
my $self = shift; |
my $self = shift; |
|
|
if ($self->ext) { return []; } |
if ($self->ext) { return []; } |
|
if (($self->is_tool()) && |
|
($self->is_gradable())) { return ['0']; } |
|
|
$self->extractParts(); |
$self->extractParts(); |
return $self->{PARTS}; |
return $self->{PARTS}; |
Line 5331 sub extractParts {
|
Line 5401 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 5615 Attempted, and not yet graded.
|
Line 5685 Attempted, and not yet graded.
|
|
|
Attempted, and credit received for attempt (survey and anonymous survey only). |
Attempted, and credit received for attempt (survey and anonymous survey only). |
|
|
|
=item * B<INCORRECT_BY_PASSBACK>: |
|
|
|
Attempted, but wrong for LTI Tool Provider by passback of grade |
|
|
|
=item * B<CORRECT_BY_PASSBACK>: |
|
|
|
Correct for LTI Tool Provider by passback of grade |
|
|
=back |
=back |
|
|
=cut |
=cut |
Line 5627 sub CORRECT_BY_OVERRIDE { return 14; }
|
Line 5705 sub CORRECT_BY_OVERRIDE { return 14; }
|
sub EXCUSED { return 15; } |
sub EXCUSED { return 15; } |
sub ATTEMPTED { return 16; } |
sub ATTEMPTED { return 16; } |
sub CREDIT_ATTEMPTED { return 17; } |
sub CREDIT_ATTEMPTED { return 17; } |
|
sub INCORRECT_BY_PASSBACK { return 18; } |
|
sub CORRECT_BY_PASSBACK { return 19; } |
|
|
sub getCompletionStatus { |
sub getCompletionStatus { |
my $self = shift; |
my $self = shift; |
Line 5641 sub getCompletionStatus {
|
Line 5721 sub getCompletionStatus {
|
if ($status eq 'correct_by_override') { |
if ($status eq 'correct_by_override') { |
return $self->CORRECT_BY_OVERRIDE; |
return $self->CORRECT_BY_OVERRIDE; |
} |
} |
|
if ($status eq 'correct_by_passback') { |
|
return $self->CORRECT_BY_PASSBACK; |
|
} |
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; } |
|
if ($status eq 'incorrect_by_passback') {return $self->INCORRECT_BY_PASSBACK; } |
if ($status eq 'excused') {return $self->EXCUSED; } |
if ($status eq 'excused') {return $self->EXCUSED; } |
if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } |
if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } |
if ($status eq 'credit_attempted') { |
if ($status eq 'credit_attempted') { |
Line 5796 sub status {
|
Line 5880 sub status {
|
|
|
# There are a few whole rows we can dispose of: |
# There are a few whole rows we can dispose of: |
if ($completionStatus == CORRECT || |
if ($completionStatus == CORRECT || |
$completionStatus == CORRECT_BY_OVERRIDE ) { |
$completionStatus == CORRECT_BY_OVERRIDE || |
|
$completionStatus == CORRECT_BY_PASSBACK ) { |
if ( $suppressFeedback ) { return ANSWER_SUBMITTED } |
if ( $suppressFeedback ) { return ANSWER_SUBMITTED } |
my $awarded=$self->awarded($part); |
my $awarded=$self->awarded($part); |
if ($awarded < 1 && $awarded > 0) { |
if ($awarded < 1 && $awarded > 0) { |
Line 5809 sub status {
|
Line 5894 sub status {
|
|
|
# If it's WRONG... and not open |
# If it's WRONG... and not open |
if ( ($completionStatus == INCORRECT || |
if ( ($completionStatus == INCORRECT || |
$completionStatus == INCORRECT_BY_OVERRIDE) |
$completionStatus == INCORRECT_BY_OVERRIDE || |
|
$completionStatus == INCORRECT_BY_PASSBACK) |
&& (!$self->opendate($part) || $self->opendate($part) > time()) ) { |
&& (!$self->opendate($part) || $self->opendate($part) > time()) ) { |
return INCORRECT; |
return INCORRECT; |
} |
} |
Line 5851 sub status {
|
Line 5937 sub status {
|
} |
} |
|
|
# If it's WRONG... |
# If it's WRONG... |
if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE) { |
if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE || |
|
$completionStatus == INCORRECT_BY_PASSBACK) { |
# and there are TRIES LEFT: |
# and there are TRIES LEFT: |
if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) { |
if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) { |
return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT; |
return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT; |
Line 5951 sub check_for_slot {
|
Line 6038 sub check_for_slot {
|
my $reservable = &Apache::lonnet::get_reservable_slots($cnum,$cdom,$env{'user.name'}, |
my $reservable = &Apache::lonnet::get_reservable_slots($cnum,$cdom,$env{'user.name'}, |
$env{'user.domain'}); |
$env{'user.domain'}); |
if (ref($reservable) eq 'HASH') { |
if (ref($reservable) eq 'HASH') { |
|
my ($map) = &Apache::lonnet::decode_symb($symb); |
if ((ref($reservable->{'now_order'}) eq 'ARRAY') && (ref($reservable->{'now'}) eq 'HASH')) { |
if ((ref($reservable->{'now_order'}) eq 'ARRAY') && (ref($reservable->{'now'}) eq 'HASH')) { |
foreach my $slot (reverse (@{$reservable->{'now_order'}})) { |
foreach my $slot (reverse (@{$reservable->{'now_order'}})) { |
my $canuse; |
my $canuse; |
if (($reservable->{'now'}{$slot}{'symb'} eq '') || |
if ($reservable->{'now'}{$slot}{'symb'} eq '') { |
($reservable->{'now'}{$slot}{'symb'} eq $symb)) { |
|
$canuse = 1; |
$canuse = 1; |
|
} else { |
|
my %oksymbs; |
|
my @slotsymbs = split(/\s*,\s*/,$reservable->{'now'}{$slot}{'symb'}); |
|
map { $oksymbs{$_} = 1; } @slotsymbs; |
|
if ($oksymbs{$symb}) { |
|
$canuse = 1; |
|
} else { |
|
foreach my $item (@slotsymbs) { |
|
if ($item =~ /\.(page|sequence)$/) { |
|
(undef,undef, my $sloturl) = &Apache::lonnet::decode_symb($item); |
|
if (($map ne '') && ($map eq $sloturl)) { |
|
$canuse = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
} |
} |
if ($canuse) { |
if ($canuse) { |
if ($checkedin) { |
if ($checkedin) { |
Line 5977 sub check_for_slot {
|
Line 6081 sub check_for_slot {
|
if ((ref($reservable->{'future_order'}) eq 'ARRAY') && (ref($reservable->{'future'}) eq 'HASH')) { |
if ((ref($reservable->{'future_order'}) eq 'ARRAY') && (ref($reservable->{'future'}) eq 'HASH')) { |
foreach my $slot (@{$reservable->{'future_order'}}) { |
foreach my $slot (@{$reservable->{'future_order'}}) { |
my $canuse; |
my $canuse; |
if (($reservable->{'future'}{$slot}{'symb'} eq '') || |
if ($reservable->{'future'}{$slot}{'symb'} eq '') { |
($reservable->{'future'}{$slot}{'symb'} eq $symb)) { |
$canuse = 1; |
|
} elsif ($reservable->{'future'}{$slot}{'symb'} =~ /,/) { |
|
my %oksymbs; |
|
my @slotsymbs = split(/\s*,\s*/,$reservable->{'future'}{$slot}{'symb'}); |
|
map { $oksymbs{$_} = 1; } @slotsymbs; |
|
if ($oksymbs{$symb}) { |
|
$canuse = 1; |
|
} else { |
|
foreach my $item (@slotsymbs) { |
|
if ($item =~ /\.(page|sequence)$/) { |
|
(undef,undef, my $sloturl) = &Apache::lonnet::decode_symb($item); |
|
if (($map ne '') && ($map eq $sloturl)) { |
|
$canuse = 1; |
|
last; |
|
} |
|
} |
|
} |
|
} |
|
} elsif ($reservable->{'future'}{$slot}{'symb'} eq $symb) { |
$canuse = 1; |
$canuse = 1; |
} |
} |
if ($canuse) { |
if ($canuse) { |
Line 6224 sub getPrevious {
|
Line 6346 sub getPrevious {
|
sub browsePriv { |
sub browsePriv { |
my $self = shift; |
my $self = shift; |
my $noblockcheck = shift; |
my $noblockcheck = shift; |
my $deeplinklisted = shift; |
|
if (defined($self->{BROWSE_PRIV})) { |
if (defined($self->{BROWSE_PRIV})) { |
return $self->{BROWSE_PRIV}; |
return $self->{BROWSE_PRIV}; |
} |
} |
my ($nodeeplinkcheck,$nodeeplinkout); |
|
if ($deeplinklisted) { |
|
my $deeplink = $self->deeplink(undef,'getlisted'); |
|
if (($deeplink) && ($deeplink ne 'absent')) { |
|
$nodeeplinkcheck = 1; |
|
} |
|
$nodeeplinkout = 1; |
|
} |
|
$self->{BROWSE_PRIV} = &Apache::lonnet::allowed('bre',$self->src(), |
$self->{BROWSE_PRIV} = &Apache::lonnet::allowed('bre',$self->src(), |
$self->{SYMB},undef, |
$self->{SYMB},undef, |
undef,$noblockcheck, |
undef,$noblockcheck); |
undef,$nodeeplinkcheck, |
|
$nodeeplinkout); |
|
} |
} |
|
|
=pod |
=pod |