--- loncom/interface/lonnavmaps.pm 2021/07/14 03:58:17 1.552
+++ loncom/interface/lonnavmaps.pm 2021/07/19 15:48:26 1.553
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Navigate Maps Handler
#
-# $Id: lonnavmaps.pm,v 1.552 2021/07/14 03:58:17 raeburn Exp $
+# $Id: lonnavmaps.pm,v 1.553 2021/07/19 15:48:26 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -1068,13 +1068,28 @@ sub render_resource {
$nonLinkedText .= ' ('.&mt('hidden').') ';
} elsif ($params->{'mapUnlisted'}) {
$nonLinkedText .= ' ('.&mt('unlisted').') ';
+ } elsif ($params->{'mapHiddenDeepLink'} || $resource->deeplinkout()) {
+ $nonLinkedText .= ' ('.&mt('not shown').') ';
}
} else {
if ($resource->randomout()) {
$nonLinkedText .= ' ('.&mt('hidden').') ';
- } elsif (($resource->deeplink($params->{caller}) eq 'absent') ||
- ($resource->deeplink($params->{caller}) eq 'grades')) {
- $nonLinkedText .= ' ('.&mt('unlisted').') ';
+ } elsif ($resource->deeplinkout()) {
+ $nonLinkedText .= ' ('.&mt('not shown').') ';
+ } else {
+ my $deeplink = $resource->deeplink($params->{caller});
+ if ((($deeplink eq 'absent') || ($deeplink eq 'grades')) &&
+ &advancedUser()) {
+ $nonLinkedText .= ' ('.&mt('unlisted').') ';
+ } elsif (($deeplink) && ($deeplink) ne 'full') {
+ if (&advancedUser()) {
+ $nonLinkedText .= ' ('.&mt('deep-link access').
+ ') ';
+ } else {
+ $nonLinkedText .= ' ('.&mt('access via external site').
+ ') ';
+ }
+ }
}
}
if (!$resource->condval()) {
@@ -1401,6 +1416,7 @@ sub render {
$filterFunc = sub { my $res = shift; return !$res->randomout() &&
($res->deeplink($args->{'caller'}) ne 'absent') &&
($res->deeplink($args->{'caller'}) ne 'grades') &&
+ !$res->deeplinkout() &&
&$oldFilterFunc($res);};
}
@@ -1821,6 +1837,7 @@ END
# If this is an empty sequence and we're filtering them, continue on
$args->{'mapHidden'} = 0;
$args->{'mapUnlisted'} = 0;
+ $args->{'mapHiddenDeepLink'} = 0;
if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) {
if ($args->{'suppressEmptySequences'}) {
next;
@@ -1833,6 +1850,12 @@ END
} else {
next;
}
+ } elsif ($curRes->deeplinkout) {
+ if ($userCanSeeHidden) {
+ $args->{'mapHiddenDeepLink'} = 1;
+ } else {
+ next;
+ }
} else {
my $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink");
if ($deeplink =~ /^(absent|grades),/) {
@@ -1906,10 +1929,10 @@ END
}
}
# If deep-link parameter is set (and is not set to full) suppress link
- # unless privileged user, or calling context is sequence, and parameter
- # set at map level
+ # unless privileged user, tinyurl used for login resolved to a map, and
+ # the resource is within the map.
if ((!$curRes->deeplink($args->{'caller'})) ||
- ($curRes->deeplink($args->{'caller'}) =~ /^full,/) || &advancedUser()) {
+ ($curRes->deeplink($args->{'caller'}) eq 'full') || &advancedUser()) {
$args->{'resource_nolink'} = 0;
} else {
$args->{'resource_nolink'} = 1;
@@ -2479,7 +2502,7 @@ sub getIterator {
my $self = shift;
my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift,
shift, undef, shift,
- shift, shift);
+ shift, shift, shift);
return $iterator;
}
@@ -3619,7 +3642,7 @@ getIterator behaves as follows:
=over 4
-=item * B(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap):
+=item * B(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap, $deeplinklisted):
All parameters are optional. firstResource is a resource reference
corresponding to where the iterator should start. It defaults to
@@ -3636,7 +3659,10 @@ that is not just a single, 'redirecting'
will return all information, starting with the top-level map,
regardless of content. returnTopMap, if true (default false), will
cause the iterator to return the top-level map object (resource 0.0)
-before anything else.
+before anything else. deeplinklisted if true (default false), will
+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
condition to a 1 without changing the hash, and all resources will be
@@ -3773,6 +3799,10 @@ sub new {
# have we done that yet?
$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
# over the parts of the map we're going to look at.
@@ -3864,7 +3894,8 @@ sub new {
$finishResource, $self->{FILTER},
$self->{ALREADY_SEEN},
$self->{CONDITION},
- $self->{FORCE_TOP});
+ $self->{FORCE_TOP},
+ undef,$self->{DEEPLINKLISTED});
}
# Set up some bookkeeping information.
@@ -4034,13 +4065,14 @@ sub next {
$finishResource, $self->{FILTER},
$self->{ALREADY_SEEN},
$self->{CONDITION},
- $self->{FORCE_TOP});
+ $self->{FORCE_TOP},
+ undef,$self->{DEEPLINKLISTED});
}
# 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
# that you can use; other things depend on this behavior.
- my $browsePriv = $self->{HERE}->browsePriv($noblockcheck);
+ my $browsePriv = $self->{HERE}->browsePriv($noblockcheck,$self->{DEEPLINKLISTED});
if (!$self->{HERE}->src() ||
(!($browsePriv eq 'F') && !($browsePriv eq '2')) ) {
return $self->next($closeAllPages);
@@ -4468,6 +4500,7 @@ sub from { my $self=shift; return $self-
sub goesto { my $self=shift; return $self->navHash("goesto_", 1); }
sub kind { my $self=shift; return $self->navHash("kind_", 1); }
sub randomout { my $self=shift; return $self->navHash("randomout_", 1); }
+sub deeplinkout { my $self=shift; return $self->navHash("deeplinkout_", 1); }
sub randompick {
my $self = shift;
my $randompick = $self->parmval('randompick');
@@ -5156,16 +5189,42 @@ sub slot_control {
return ($useslots,$availablestudent,$available);
}
sub deeplink {
- my ($self,$caller) = @_;
- my $value = $self->parmval("deeplink");
- if ($value) {
- my @deeplink = split(/,/,$value);
- if ($caller eq 'sequence') {
- if ($deeplink[1] ne 'res') {
- return;
+ my ($self,$caller,$action) = @_;
+ my $deeplink = $self->parmval("deeplink");
+ if ($deeplink) {
+ my ($listed,$scope,$access) = split(/,/,$deeplink);
+ if ($action eq 'getlisted') {
+ 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));
+ }
}
}
- return $deeplink[0];
+ unless (($caller eq 'sequence') || ($access eq 'any')) {
+ return $listed;
+ }
}
return;
}
@@ -6360,13 +6419,23 @@ sub getPrevious {
sub browsePriv {
my $self = shift;
my $noblockcheck = shift;
+ my $deeplinklisted = shift;
if (defined($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->{SYMB},undef,
- undef,$noblockcheck);
+ undef,$noblockcheck,
+ undef,$nodeeplinkcheck,
+ $nodeeplinkout);
}
=pod