--- loncom/interface/lonnavmaps.pm 2023/07/06 20:32:17 1.509.2.14.2.9 +++ loncom/interface/lonnavmaps.pm 2025/02/03 03:04:24 1.570 @@ -1,8 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.509.2.14.2.9 2023/07/06 20:32:17 raeburn Exp $ - +# $Id: lonnavmaps.pm,v 1.570 2025/02/03 03:04:24 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -49,12 +48,20 @@ described at http://www.lon-capa.org. =head1 OVERVIEW -X When a user enters a course, LON-CAPA examines the +X +When a user enters a course, LON-CAPA examines the course structure and caches it in what is often referred to as the "big hash" X. You can see it if you are logged into -LON-CAPA, in a course, by going to /adm/test. (You may need to -tweak the /home/httpd/lonTabs/htpasswd file to view it.) The -content of the hash will be under the heading "Big Hash". +LON-CAPA, in a course, by going to /adm/test. The 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 to each other (next/previous), what resources are maps, which @@ -65,7 +72,7 @@ processed. Apache::lonnavmaps provides an object model for manipulating this 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- resource sort of value, like whether there is any feedback on a given resource. @@ -78,11 +85,18 @@ Apache::lonnavmaps also provides fairly rendering navmaps, and last but not least, provides the navmaps view for when the user clicks the NAV button. -B: Apache::lonnavmaps I works for the "currently -logged in user"; if you want things like "due dates for another -student" lonnavmaps can not directly retrieve information like -that. You need the EXT function. This module can still help, -because many things, such as the course structure, are constant +B: Apache::lonnavmaps by default will show information +for the "currently logged in user". However, if information +about resources is needed for a different user, e.g., a bubblesheet +exam which uses randomorder, or randompick needs to be printed or +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 symbs for the EXT call. @@ -92,7 +106,9 @@ all, then documents the Apache::lonnavma is the key to accessing the Big Hash information, covers the use of the Iterator (which provides the logic for traversing 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 @@ -956,8 +972,6 @@ sub render_resource { $newBranchText = ".mt('Branch')."; } - # links to open and close the folder - my $whitespace = $location.'/whitespace_21.gif'; my ($nomodal,$linkopen,$linkclose); unless ($resource->is_map() || $params->{'resource_nolink'}) { @@ -1049,7 +1063,7 @@ sub render_resource { } } 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/)) { if (!$params->{'map_no_edit_link'}) { my $icon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png'; @@ -1107,7 +1121,7 @@ sub render_resource { } # Decide what to display - $result .= "$newBranchText$linkopen$icon$linkclose"; + $result .= "$newBranchText$linkopen$icon"; my $curMarkerBegin = ''; my $curMarkerEnd = ''; @@ -1147,7 +1161,7 @@ sub render_resource { $linkopen = ""; } } - $result .= "$curMarkerBegin$linkopen$title$partLabel$linkclose$curMarkerEnd$editmapLink$nonLinkedText"; + $result .= "$curMarkerBegin$title$partLabel$curMarkerEnd$linkclose$editmapLink$nonLinkedText"; return $result; } @@ -1248,7 +1262,7 @@ sub render_long_status { } } } - + if (($resource->kind() eq "res") && ($resource->is_raw_problem() || $resource->is_gradable()) && !$firstDisplayed) { @@ -1408,7 +1422,7 @@ sub render { # Without renaming the filterfunc, the server seems to go into # an infinite loop 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 'grades') && !$res->deeplinkout() && @@ -1472,11 +1486,11 @@ sub render { my $currenturl = $env{'form.postdata'}; #$currenturl=~s/^http\:\/\///; #$currenturl=~s/^[^\/]+//; - unless ($args->{'caller'} eq 'sequence') { + unless ($args->{'caller'} eq 'sequence') { $here = $jump = &Apache::lonnet::symbread($currenturl); } } - if (($here eq '') && ($args->{'caller'} ne 'sequence')) { + if (($here eq '') && ($args->{'caller'} ne 'sequence')) { my $last; if (tie(my %hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', &GDBM_READER(),0640)) { @@ -1490,7 +1504,7 @@ sub render { my $mapIterator = $navmap->getIterator(undef, undef, undef, 1); my $curRes; my $found = 0; - my $here_is_navmaps = 0; + my $here_is_navmaps = 0; if ($here =~ m{___\d+___adm/navmaps$}) { $here_is_navmaps = 1; } @@ -1562,7 +1576,12 @@ sub render { while (($curRes = $mapIterator->next()) && !$foundJump) { if (ref($curRes)) { $counter++; } - + # Speed up display after course initialization + # when $jump is empty. Note: we still need + # $counter to be 1 in that case if there is at + # least one resource. + last if (($jump eq '') && ($counter)); + if (ref($curRes) && $jump eq $curRes->symb()) { # This is why we have to use the main iterator instead of the @@ -1581,27 +1600,18 @@ sub render { my $printKey = $args->{'printKey'}; my $printCloseAll = $args->{'printCloseAll'}; if (!defined($printCloseAll)) { $printCloseAll = 1; } - + # Print key? if ($printKey) { - $result .= ''; - $result.=''; - my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); - if ($navmap->{LAST_CHECK}) { - $result .= - ' '.&mt('New discussion since').' '. - strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). - ''; - } else { - $result .= ''; - } - - $result .= '
Key:    '. - ' '.&mt('New message (click to open)').'

'. - '

  '. - ' '.&mt('Discussions').''. - '   '.&mt('New message (click to open)'). - '
'; + my $location = &Apache::loncommon::lonhttpdurl("/adm/lonMisc"); + $result .= ''. + ''. + '
Key:    '. + ' '.&mt('Unread Discussion'). + ''. + '   '. + &mt('New message (click to open)'). + '
'."\n"; } if ($printCloseAll && !$args->{'resource_no_folder_link'}) { @@ -1628,17 +1638,19 @@ sub render { # Check for any unread discussions in all resources. if (($args->{'caller'} eq 'navmapsdisplay') && (!$args->{'notools'})) { + my $markread = 'Mark all posts read'; &add_linkitem($args->{'linkitems'},'clearbubbles', 'document.clearbubbles.submit()', - 'Mark all posts read'); + $markread); my $time=time; + my $submit = &mt($markread); my $querystr = &HTML::Entities::encode($ENV{'QUERY_STRING'},'<>&"'); $result .= (< +