--- loncom/interface/lonnavmaps.pm 2021/12/31 23:14:04 1.509.2.14 +++ loncom/interface/lonnavmaps.pm 2015/10/05 01:52:10 1.510 @@ -1,8 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.509.2.14 2021/12/31 23:14:04 raeburn Exp $ - +# $Id: lonnavmaps.pm,v 1.510 2015/10/05 01:52:10 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -486,7 +485,7 @@ use Apache::lonlocal; use Apache::lonnet; use Apache::lonmap; -use POSIX qw (ceil floor strftime); +use POSIX qw (floor strftime); use Time::HiRes qw( gettimeofday tv_interval ); use LONCAPA; use DateTime(); @@ -577,11 +576,7 @@ sub getLinkForResource { my $anchor; if ($res->is_page()) { foreach my $item (@$stack) { if (defined($item)) { $anchor = $item; } } - if ($anchor->encrypted() && !&advancedUser()) { - $anchor='LC_'.$anchor->id(); - } else { - $anchor=&escape($anchor->shown_symb()); - } + $anchor=&escape($anchor->shown_symb()); return ($res->link(),$res->shown_symb(),$anchor); } # in case folder was skipped over as "only sequence" @@ -647,9 +642,6 @@ sub getDescription { } elsif ($slot_status == $res->RESERVABLE) { $slotmsg = &mt('Reservable, reservations close [_1]', timeToHumanString($slot_time,'end')); - } elsif ($slot_status == $res->NEEDS_CHECKIN) { - $slotmsg = &mt('Reserved, check-in needed - ends [_1]', - timeToHumanString($slot_time,'end')); } elsif ($slot_status == $res->RESERVABLE_LATER) { $slotmsg = &mt('Reservable, reservations open [_1]', timeToHumanString($slot_time,'start')); @@ -922,9 +914,6 @@ sub render_resource { my $nonLinkedText = ''; # stuff after resource title not in link my $link = $params->{"resourceLink"}; - if ($resource->ext()) { - $link =~ s/\#.+(\?)/$1/g; - } # The URL part is not escaped at this point, but the symb is... @@ -945,28 +934,7 @@ sub render_resource { # links to open and close the folder my $whitespace = $location.'/whitespace_21.gif'; - my $linkopen = ""; - my $nomodal; - if (($params->{'modalLink'}) && (!$resource->is_sequence())) { - if ($link =~m{^(?:|/adm/wrapper)/ext/([^#]+)}) { - my $exturl = $1; - if (($ENV{'SERVER_PORT'} == 443) && ($exturl !~ /^https:/)) { - $nomodal = 1; - } - } elsif (($link eq "/public/$LONCAPA::match_domain/$LONCAPA::match_courseid/syllabus") && - ($env{'request.course.id'}) && ($ENV{'SERVER_PORT'} == 443) && - ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { - $nomodal = 1; - } - my $esclink = &js_escape($link); - if ($nomodal) { - $linkopen .= ""; - } else { - $linkopen .= ""; - } - } else { - $linkopen .= ""; - } + my $linkopen = "".""; my $linkclose = ""; # Default icon: unknown page @@ -1020,15 +988,11 @@ sub render_resource { # Don't allow users to manipulate folder $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif'; $icon = ""."\"".($nowOpen"; - if ($params->{'caller'} eq 'sequence') { - $linkopen = ""; - } else { - $linkopen = ""; - $linkclose = ""; - } + + $linkopen = ""; + $linkclose = ""; } - if (((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || - (&Apache::lonnet::allowed('cev',$env{'request.course.id'}))) && + if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) && ($resource->symb=~/\_\_\_[^\_]+\_\_\_uploaded/)) { if (!$params->{'map_no_edit_link'}) { my $icon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png'; @@ -1038,13 +1002,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').') '; @@ -1094,19 +1055,10 @@ sub render_resource { } if (!$params->{'resource_nolink'} && !$resource->is_sequence() && !$resource->is_empty_sequence) { - $linkclose = ''; - if ($params->{'modalLink'}) { - my $esclink = &js_escape($link); - if ($nomodal) { - $linkopen = ""; - } else { - $linkopen = ""; - } - } else { - $linkopen = ""; - } + $result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$editmapLink$nonLinkedText"; + } else { + $result .= "$curMarkerBegin$linkopen$title$partLabel$curMarkerEnd$editmapLink$nonLinkedText"; } - $result .= "$curMarkerBegin$linkopen$title$partLabel$linkclose$curMarkerEnd$editmapLink$nonLinkedText"; return $result; } @@ -1397,11 +1349,10 @@ sub render { my $currenturl = $env{'form.postdata'}; #$currenturl=~s/^http\:\/\///; #$currenturl=~s/^[^\/]+//; - 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 '') { my $last; if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', &GDBM_READER(),0640)) { @@ -1461,13 +1412,10 @@ sub render { if ($args->{'iterator_map'}) { my $map = $args->{'iterator_map'}; $map = $navmap->getResourceByUrl($map); - if (ref($map)) { - my $firstResource = $map->map_start(); - my $finishResource = $map->map_finish(); - $args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition); - } else { - return; - } + my $firstResource = $map->map_start(); + my $finishResource = $map->map_finish(); + + $args->{'iterator'} = $it = $navmap->getIterator($firstResource, $finishResource, $filterHash, $condition); } else { $args->{'iterator'} = $it = $navmap->getIterator(undef, undef, $filterHash, $condition,undef,$args->{'include_top_level_map'}); } @@ -1586,8 +1534,7 @@ END $result.=''; } if (($args->{'caller'} eq 'navmapsdisplay') && - ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || - (&Apache::lonnet::allowed('cev',$env{'request.course.id'})))) { + (&Apache::lonnet::allowed('mdc',$env{'request.course.id'}))) { my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; if ($env{'course.'.$env{'request.course.id'}.'.url'} eq @@ -1633,46 +1580,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; @@ -1730,28 +1672,6 @@ END undef($args->{'sort'}); } - # Determine if page will be served with https in case - # it contains a syllabus which uses an external URL - # which points at an http site. - - my ($is_ssl,$cdom,$cnum,$hostname); - if ($ENV{'SERVER_PORT'} == 443) { - $is_ssl = 1; - if ($r) { - $hostname = $r->hostname(); - } else { - $hostname = $ENV{'SERVER_NAME'}; - } - } - if ($env{'request.course.id'}) { - $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - } - - my $inhibitmenu; - if ($args->{'modalLink'}) { - $inhibitmenu = '&inhibitmenu=yes'; - } while (1) { if ($args->{'sort'}) { @@ -1787,21 +1707,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 @@ -1885,35 +1793,11 @@ END $stack=$it->getStack(); } ($src,$symb,$anchor)=getLinkForResource($stack); - my $srcHasQuestion = $src =~ /\?/; - if ($env{'request.course.id'}) { - if (($is_ssl) && ($src =~ m{^\Q/public/$cdom/$cnum/syllabus\E($|\?)}) && - ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { - unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { - if ($hostname ne '') { - $src = 'http://'.$hostname.$src; - } - $src .= ($srcHasQuestion? '&' : '?') . 'usehttp=1'; - $srcHasQuestion = 1; - } - } elsif (($is_ssl) && ($src =~ m{^\Q/adm/wrapper/ext/\E(?!https:)})) { - unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { - if ($hostname ne '') { - $src = 'http://'.$hostname.$src; - } - $src .= ($srcHasQuestion? '&' : '?') . 'usehttp=1'; - $srcHasQuestion = 1; - } - } - } if (defined($anchor)) { $anchor='#'.$anchor; } - if (($args->{'caller'} eq 'sequence') && ($curRes->is_map())) { - $args->{"resourceLink"} = $src.($srcHasQuestion?'&':'?') .'navmap=1'; - } else { - $args->{"resourceLink"} = $src. - ($srcHasQuestion?'&':'?') . - 'symb=' . &escape($symb).$inhibitmenu.$anchor; - } + my $srcHasQuestion = $src =~ /\?/; + $args->{"resourceLink"} = $src. + ($srcHasQuestion?'&':'?') . + 'symb=' . &escape($symb).$anchor; } # Now, we've decided what parts to show. Loop through them and # show them. @@ -1941,7 +1825,7 @@ END $currentJumpDelta) { # Jam the anchor after the tag; # necessary for valid HTML (which Mozilla requires) - $colHTML =~ s/\>/\>\\<\/a\>/; + $colHTML =~ s/\>/\>\/; $displayedJumpMarker = 1; } $result .= $colHTML . "\n"; @@ -2327,7 +2211,7 @@ sub generate_email_discuss_status { foreach my $msgid (@keys) { if ((!$emailstatus{$msgid}) || ($emailstatus{$msgid} eq 'new')) { my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid, - $symb,$error) = &Apache::lonmsg::unpackmsgid(&LONCAPA::escape($msgid)); + $symb,$error) = &Apache::lonmsg::unpackmsgid($msgid); &Apache::lonenc::check_decrypt(\$symb); if (($fromcid ne '') && ($fromcid ne $cid)) { next; @@ -2824,108 +2708,6 @@ sub parmval_real { if (defined($pack_def)) { return [$pack_def,'resource']; } return ['']; } - -sub recurseup_maps { - my ($self,$mapname) = @_; - my @recurseup; - if ($mapname) { - my $res = $self->getResourceByUrl($mapname); - if (ref($res)) { - my @pcs = split(/,/,$res->map_hierarchy()); - shift(@pcs); - if (@pcs) { - @recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); - } - } - } - return @recurseup; -} - -sub recursed_crumbs { - my ($self,$mapurl,$restitle) = @_; - my (@revmapinfo,@revmapres); - my $mapres = $self->getResourceByUrl($mapurl); - if (ref($mapres)) { - @revmapres = map { $self->getByMapPc($_); } split(/,/,$mapres->map_breadcrumbs()); - shift(@revmapres); - } - my $allowedlength = 60; - my $minlength = 5; - my $allowedtitle = 30; - if (($env{'environment.icons'} eq 'iconsonly') && (!$env{'browser.mobile'})) { - $allowedlength = 100; - $allowedtitle = 70; - } - if (length($restitle) > $allowedtitle) { - $restitle = &truncate_crumb_text($restitle,$allowedtitle); - } - my $totallength = length($restitle); - my @links; - - foreach my $map (@revmapres) { - my $pc = $map->map_pc(); - next if ((!$pc) || ($pc == 1)); - push(@links,$map); - push(@revmapinfo,{'href' => $env{'request.use_absolute'}.$map->link().'?navmap=1','text' => $map->title(),'no_mt' => 1,}); - $totallength += length($map->title()); - } - my $numlinks = scalar(@links); - if ($numlinks) { - if ($totallength - $allowedlength > 0) { - my $available = $allowedlength - length($restitle); - my $avg = POSIX::ceil($available/$numlinks); - if ($avg < $minlength) { - $avg = $minlength; - } - @revmapinfo = (); - foreach my $map (@links) { - my $showntitle = &truncate_crumb_text($map->title(),$avg); - if ($showntitle ne '') { - push(@revmapinfo,{'href' => $env{'request.use_absolute'}.$map->link().'?navmap=1','text' => $showntitle,'no_mt' => 1,}); - } - } - } - } - if ($restitle ne '') { - push(@revmapinfo,{'text' => $restitle, 'no_mt' => 1}); - } - return @revmapinfo; -} - -sub truncate_crumb_text { - my ($title,$limit) = @_; - my $showntitle = ''; - if (length($title) > $limit) { - my @words = split(/\b\s*/,$title); - if (@words == 1) { - $showntitle = substr($title,0,$limit).' ...'; - } else { - my $linklength = 0; - my $num = 0; - foreach my $word (@words) { - $linklength += 1+length($word); - if ($word eq '-') { - $showntitle =~ s/ $//; - $showntitle .= $word; - } elsif ($linklength > $limit) { - if ($num < @words) { - $showntitle .= $word.' ...'; - last; - } else { - $showntitle .= $word; - } - } else { - $showntitle .= $word.' '; - } - } - $showntitle =~ s/ $//; - } - return $showntitle; - } else { - return $title; - } -} - # # Determines the open/close dates for printing a map that # encloses a resource. @@ -2937,15 +2719,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: @@ -2964,17 +2746,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\_//; @@ -3006,20 +2786,6 @@ sub get_mapparam { if (defined($$useropt{$courselevel})) { return $$useropt{$courselevel}; } - if ($what =~ /\.(encrypturl|hiddenresource)$/) { - 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}; - } - } - } - } } # Check course -- group @@ -3030,20 +2796,6 @@ sub get_mapparam { if (defined($$courseopt{$grplevel})) { return $$courseopt{$grplevel}; } - if ($what =~ /\.(encrypturl|hiddenresource)$/) { - 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}; - } - } - } - } } # Check course -- section @@ -3056,29 +2808,12 @@ sub get_mapparam { if (defined($$courseopt{$seclevel})) { return $$courseopt{$seclevel}; } - if ($what =~ /\.(encrypturl|hiddenresource)$/) { - 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}; - } - } - } - } } # 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; } @@ -3088,20 +2823,6 @@ sub get_mapparam { if (defined($$courseopt{$courselevel})) { return $$courseopt{$courselevel}; } - if ($what =~ /\.(encrypturl|hiddenresource)$/) { - 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}; - } - } - } - } } return undef; # Unefined if we got here. } @@ -3157,7 +2878,7 @@ sub getcourseparam { # # We want the course level stuff from the way # parmval_real operates - # TODO: Factor some of this stuff out of + # TODO: Fator some of this stuff out of # both parmval_real and here # my $courselevel = $cid . '.' . $what; @@ -3174,7 +2895,7 @@ sub getcourseparam { } # Try for the group's course level option: - if ($cgroup ne '' and defined($courseopt)) { + if ($uname ne '' and defined($courseopt)) { if (defined($$courseopt{$grplevel})) { return $$courseopt{$grplevel}; } @@ -3182,12 +2903,12 @@ sub getcourseparam { # Try for section level parameters: - if ($csec ne '' and defined($courseopt)) { + if ($csec and defined($courseopt)) { if (defined($$courseopt{$seclevel})) { return $$courseopt{$seclevel}; } } - # Try for 'additional' course parameters: + # Try for 'additional' course parameterse: if (defined($courseopt)) { if (defined($$courseopt{$courselevel})) { @@ -3799,8 +3520,7 @@ 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}) && - ($env{'request.role.adv'} || !$self->{HERE}->randomout())) { + (defined($self->{FILTER}->{$self->{HERE}->map_pc()}) xor $self->{CONDITION})) { $self->{RECURSIVE_ITERATOR_FLAG} = 1; my $firstResource = $self->{HERE}->map_start(); my $finishResource = $self->{HERE}->map_finish(); @@ -4278,7 +3998,6 @@ sub enclosing_map_src { } sub symb { my $self=shift; - if (defined($self->{SYMB})) { return $self->{SYMB}; } (my $first, my $second) = $self->{ID} =~ /(\d+).(\d+)/; my $symbSrc = &Apache::lonnet::declutter($self->src()); my $symb = &Apache::lonnet::declutter($self->navHash('map_id_'.$first)) @@ -4549,12 +4268,6 @@ Returns a string with a comma-separated for the hierarchy of maps containing a map, with the top level map first, then descending to deeper levels, with the enclosing map last. -=item * B: - -Same as map_hierarchy, except maps containing only a single itemm if -it's a map, or containing no items are omitted, unless it's the top -level map (map_pc = 1), which is always included. - =back =cut @@ -4590,11 +4303,6 @@ sub map_hierarchy { my $pc = $self->map_pc(); return $self->navHash("map_hierarchy_$pc", 0); } -sub map_breadcrumbs { - my $self = shift; - my $pc = $self->map_pc(); - return $self->navHash("map_breadcrumbs_$pc", 0); -} ##### # Property queries @@ -4821,7 +4529,7 @@ sub duedate { my $due_date=$self->parmval("duedate", $part); if ($interval[0] =~ /\d+/) { my $first_access=&Apache::lonnet::get_first_access($interval[1], - $self->{SYMB}); + $self->symb); if (defined($first_access)) { my $interval = $first_access+$interval[0]; $date = (!$due_date || $interval < $due_date) ? $interval @@ -4903,7 +4611,7 @@ sub part_display { my $self= shift(); my $partID = shift(); if (! defined($partID)) { $partID = '0'; } my $display=&Apache::lonnet::EXT('resource.'.$partID.'.display', - $self->{SYMB}); + $self->symb); if (! defined($display) || $display eq '') { $display = $partID; } @@ -5699,13 +5407,14 @@ 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); + my ($map) = &Apache::lonnet::decode_symb($symb); foreach my $slot_name (@sorted_slots) { next if (!defined($slots{$slot_name}) || !ref($slots{$slot_name})); my $end = $slots{$slot_name}->{'endtime'}; @@ -5729,7 +5438,7 @@ sub check_for_slot { ($checkedin,$checkedinslot) = $self->checkedin(); unless ((grep(/^\Q$checkedin\E/,@proctors)) && ($checkedinslot eq $slot_name)) { - return (NEEDS_CHECKIN,$end,$slot_name); + return (NEEDS_CHECKIN,undef,$slot_name); } } return (RESERVED,$end,$slot_name); @@ -5739,30 +5448,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); @@ -5778,22 +5476,27 @@ sub check_for_slot { 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'}); } } @@ -5801,22 +5504,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'}); } }