(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
@@ -3411,7 +3464,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
@@ -3548,6 +3604,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.
@@ -3639,7 +3699,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.
@@ -3799,7 +3860,8 @@ sub next {
# That ends the main iterator logic. Now, do we want to recurse
# down this map (if this resource is a map)?
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;
my $firstResource = $self->{HERE}->map_start();
my $finishResource = $self->{HERE}->map_finish();
@@ -3808,13 +3870,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);
@@ -4242,6 +4305,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');
@@ -4497,7 +4561,6 @@ sub is_task {
sub is_empty_sequence {
my $self=shift;
- my $src = $self->src();
return !$self->is_page() && $self->navHash("is_map_", 1) && !$self->navHash("map_type_" . $self->map_pc());
}
@@ -4818,11 +4881,12 @@ sub duedate {
my $date;
my @interval=$self->parmval("interval", $part);
my $due_date=$self->parmval("duedate", $part);
- if ($interval[0] =~ /\d+/) {
- my $first_access=&Apache::lonnet::get_first_access($interval[1],
+ if ($interval[0] =~ /(\d+)/) {
+ my $timelimit = $1;
+ my $first_access=&Apache::lonnet::get_first_access($interval[1],
$self->{SYMB});
if (defined($first_access)) {
- my $interval = $first_access+$interval[0];
+ my $interval = $first_access+$timelimit;
$date = (!$due_date || $interval < $due_date) ? $interval
: $due_date;
} else {
@@ -4916,6 +4980,46 @@ sub slot_control {
my $available = $self->parmval("available", $part);
return ($useslots,$availablestudent,$available);
}
+sub deeplink {
+ my ($self,$caller,$action) = @_;
+ my $deeplink = $self->parmval("deeplink");
+ if ($deeplink) {
+ my ($state,$others,$listed,$scope) = 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));
+ }
+ }
+ }
+ unless (($caller eq 'sequence') || ($state eq 'both')) {
+ return $listed;
+ }
+ }
+ return;
+}
# Multiple things need this
sub getReturnHash {
@@ -6047,13 +6151,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
500 Internal Server Error
Internal Server Error
The server encountered an internal error or
misconfiguration and was unable to complete
your request.
Please contact the server administrator at
root@localhost to inform them of the time this error occurred,
and the actions you performed just before this error.
More information about this error may be available
in the server error log.