--- loncom/interface/lonnavmaps.pm 2016/08/10 21:29:52 1.509.2.3 +++ loncom/interface/lonnavmaps.pm 2016/03/02 14:06:30 1.514 @@ -1,8 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.509.2.3 2016/08/10 21:29:52 raeburn Exp $ - +# $Id: lonnavmaps.pm,v 1.514 2016/03/02 14:06:30 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1006,13 +1005,10 @@ sub render_resource { ''; } } - if ($params->{'mapHidden'} || $resource->randomout()) { - $nonLinkedText .= ' ('.&mt('hidden').') '; - } - } else { - if ($resource->randomout()) { - $nonLinkedText .= ' ('.&mt('hidden').') '; - } + } + + if ($resource->randomout()) { + $nonLinkedText .= ' ('.&mt('hidden').') '; } if (!$resource->condval()) { $nonLinkedText .= ' ('.&mt('conditionally hidden').') '; @@ -1587,46 +1583,41 @@ END $args->{'indentString'} = setDefault($args->{'indentString'}, ""); $args->{'displayedHereMarker'} = 0; - # If we're suppressing empty sequences, look for them here. - # We also do this even if $args->{'suppressEmptySequences'} - # is not true, so we can hide empty sequences for which the - # hiddenresource parameter is set to yes (at map level), or - # mark as hidden for users who have $userCanSeeHidden. - # Use DFS for speed, since structure actually doesn't matter, - # except what map has what resources. - - my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, - $it->{FIRST_RESOURCE}, - $it->{FINISH_RESOURCE}, - {}, undef, 1); - - my $depth = 0; - $dfsit->next(); - my $curRes = $dfsit->next(); - while ($depth > -1) { - if ($curRes == $dfsit->BEGIN_MAP()) { $depth++; } - if ($curRes == $dfsit->END_MAP()) { $depth--; } - - if (ref($curRes)) { - # Parallel pre-processing: Do sequences have non-filtered-out children? - if ($curRes->is_map()) { - $curRes->{DATA}->{HAS_VISIBLE_CHILDREN} = 0; - # Sequences themselves do not count as visible children, - # unless those sequences also have visible children. - # This means if a sequence appears, there's a "promise" - # that there's something under it if you open it, somewhere. - } 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; + # If we're suppressing empty sequences, look for them here. Use DFS for speed, + # since structure actually doesn't matter, except what map has what resources. + if ($args->{'suppressEmptySequences'}) { + my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, + $it->{FIRST_RESOURCE}, + $it->{FINISH_RESOURCE}, + {}, undef, 1); + my $depth = 0; + $dfsit->next(); + my $curRes = $dfsit->next(); + while ($depth > -1) { + if ($curRes == $dfsit->BEGIN_MAP()) { $depth++; } + if ($curRes == $dfsit->END_MAP()) { $depth--; } + + if (ref($curRes)) { + # Parallel pre-processing: Do sequences have non-filtered-out children? + if ($curRes->is_map()) { + $curRes->{DATA}->{HAS_VISIBLE_CHILDREN} = 0; + # Sequences themselves do not count as visible children, + # unless those sequences also have visible children. + # This means if a sequence appears, there's a "promise" + # that there's something under it if you open it, somewhere. + } else { + # 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; @@ -1719,21 +1710,9 @@ END } # If this is an empty sequence and we're filtering them, continue on - $args->{'mapHidden'} = 0; - if (($curRes->is_map()) && (!$curRes->{DATA}->{HAS_VISIBLE_CHILDREN})) { - 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 ($curRes->is_map() && $args->{'suppressEmptySequences'} && + !$curRes->{DATA}->{HAS_VISIBLE_CHILDREN}) { + next; } # If we're suppressing navmaps and this is a navmap, continue on @@ -2142,7 +2121,7 @@ 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. $self->{PARM_CACHE} = {}; @@ -2743,15 +2722,15 @@ sub map_printdates { - my $opendate = $self->get_mapparam($res->symb(),'',"$part.printstartdate"); - my $closedate= $self->get_mapparam($res->symb(),'', "$part.printenddate"); + my $opendate = $self->get_mapparam($res->symb(), "$part.printstartdate"); + my $closedate= $self->get_mapparam($res->symb(), "$part.printenddate"); return ($opendate, $closedate); } sub get_mapparam { - my ($self, $symb, $mapname, $what) = @_; + my ($self, $symb, $what) = @_; # Ensure the course option hash is populated: @@ -2770,17 +2749,15 @@ sub get_mapparam { my $uname=$self->{USERNAME}; my $udom=$self->{DOMAIN}; - unless ($symb || $mapname) { return; } + unless ($symb) { return ['']; } my $result=''; - my ($recursed,@recurseup); + # Figure out which map we are in. - if ($symb && !$mapname) { - my ($id,$fn); - ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); - $mapname = &Apache::lonnet::deversion($mapname); - } + my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); + $mapname = &Apache::lonnet::deversion($mapname); + my $rwhat=$what; $what=~s/^parameter\_//; @@ -2837,12 +2814,9 @@ sub get_mapparam { } # Check the map parameters themselves: - if ($symb) { - my $symbparm=$symb.'.'.$what; - my $thisparm = $$parmhash{$symbparm}; - if (defined($thisparm)) { - return $thisparm; - } + my $thisparm = $$parmhash{$symbparm}; + if (defined($thisparm)) { + return $thisparm; } @@ -5436,13 +5410,13 @@ sub check_for_slot { my $cnum=$env{'course.'.$cid.'.num'}; my $now = time; my $num_usable_slots = 0; - my ($checkedin,$checkedinslot,%consumed_uniq,%slots); if (@slots > 0) { - %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum); + my %slots=&Apache::lonnet::get('slots',[@slots],$cdom,$cnum); if (&Apache::lonnet::error(%slots)) { return (UNKNOWN); } my @sorted_slots = &Apache::loncommon::sorted_slots(\@slots,\%slots,'starttime'); + my ($checkedin,$checkedinslot); foreach my $slot_name (@sorted_slots) { next if (!defined($slots{$slot_name}) || !ref($slots{$slot_name})); my $end = $slots{$slot_name}->{'endtime'}; @@ -5476,30 +5450,19 @@ sub check_for_slot { $num_usable_slots ++; } } - my ($is_correct,$wait_for_grade); + my ($is_correct,$got_grade); if ($self->is_task()) { my $taskstatus = $self->taskstatus(); $is_correct = (($taskstatus eq 'pass') || ($self->solved() =~ /^correct_/)); - unless ($taskstatus =~ /^(?:pass|fail)$/) { - $wait_for_grade = 1; - } + $got_grade = ($taskstatus =~ /^(?:pass|fail)$/); } else { - unless ($self->completable()) { - $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; - } + $got_grade = 1; + $is_correct = ($self->solved() =~ /^correct_/); } ($checkedin,$checkedinslot) = $self->checkedin(); if ($checkedin) { - if (ref($slots{$checkedinslot}) eq 'HASH') { - $consumed_uniq{$checkedinslot} = $slots{$checkedinslot}{'uniqueperiod'}; - } - if ($wait_for_grade) { + if (!$got_grade) { return (WAITING_FOR_GRADE); } elsif ($is_correct) { return (CORRECT); @@ -5512,25 +5475,31 @@ sub check_for_slot { my $reservable = &Apache::lonnet::get_reservable_slots($cnum,$cdom,$env{'user.name'}, $env{'user.domain'}); if (ref($reservable) eq 'HASH') { + my ($map) = &Apache::lonnet::decode_symb($symb); if ((ref($reservable->{'now_order'}) eq 'ARRAY') && (ref($reservable->{'now'}) eq 'HASH')) { foreach my $slot (reverse (@{$reservable->{'now_order'}})) { my $canuse; - if (($reservable->{'now'}{$slot}{'symb'} eq '') || - ($reservable->{'now'}{$slot}{'symb'} eq $symb)) { + if ($reservable->{'now'}{$slot}{'symb'} eq '') { $canuse = 1; - } - 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 )); + } 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) { return(RESERVABLE,$reservable->{'now'}{$slot}{'endreserve'}); } } @@ -5538,22 +5507,29 @@ sub check_for_slot { if ((ref($reservable->{'future_order'}) eq 'ARRAY') && (ref($reservable->{'future'}) eq 'HASH')) { foreach my $slot (@{$reservable->{'future_order'}}) { my $canuse; - if (($reservable->{'future'}{$slot}{'symb'} eq '') || - ($reservable->{'future'}{$slot}{'symb'} eq $symb)) { + if ($reservable->{'future'}{$slot}{'symb'} eq '') { $canuse = 1; - } - 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 )); + } 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; + } + if ($canuse) { return(RESERVABLE_LATER,$reservable->{'future'}{$slot}{'startreserve'}); } }