--- loncom/interface/lonnavmaps.pm 2023/07/06 20:32:17 1.509.2.14.2.9 +++ loncom/interface/lonnavmaps.pm 2024/07/01 18:13:20 1.509.2.15 @@ -1,7 +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.509.2.15 2024/07/01 18:13:20 raeburn Exp $ # # Copyright Michigan State University Board of Trustees @@ -534,10 +534,6 @@ my %colormap = $resObj->EXCUSED => '#3333FF', $resObj->PAST_DUE_ANSWER_LATER => '', $resObj->PAST_DUE_NO_ANSWER => '', - $resObj->PAST_DUE_ATMPT_ANS => '', - $resObj->PAST_DUE_ATMPT_NOANS => '', - $resObj->PAST_DUE_NO_ATMT_ANS => '', - $resObj->PAST_DUE_NO_ATMT_NOANS => '', $resObj->ANSWER_OPEN => '#006600', $resObj->OPEN_LATER => '', $resObj->TRIES_LEFT => '', @@ -683,10 +679,10 @@ sub getDescription { return &Apache::lonhtmlcommon::direct_parm_link(&mt("Open, no due date"),$res->symb(),'duedate',$part).$slotinfo; } } - if (($status == $res->PAST_DUE_ANSWER_LATER) || ($status == $res->PAST_DUE_ATMPT_ANS) || ($status == $res->PAST_DUE_NO_ATMT_ANS)) { + if ($status == $res->PAST_DUE_ANSWER_LATER) { return &mt("Answer open [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($answer,'start'),$res->symb(),'answerdate',$part)); } - if (($status == $res->PAST_DUE_NO_ANSWER) || ($status == $res->PAST_DUE_ATMPT_NOANS) || ($status == $res->PAST_DUE_NO_ATMT_NOANS)) { + if ($status == $res->PAST_DUE_NO_ANSWER) { if ($res->is_practice()) { return &mt("Closed [_1]",&Apache::lonhtmlcommon::direct_parm_link(&timeToHumanString($due,'start'),$res->symb(),'answerdate,duedate',$part)); } else { @@ -695,17 +691,7 @@ sub getDescription { } if (($status == $res->ANSWER_OPEN || $status == $res->PARTIALLY_CORRECT) && $res->handgrade($part) ne 'yes') { - my $msg = &mt('Answer available'); - my $parmlist = 'answerdate,duedate'; - if (($res->is_tool) && ($res->is_gradable())) { - if (($status == $res->PARTIALLY_CORRECT) && ($res->parmval('retrypartial',$part))) { - $msg = &mt('Grade received'); - $parmlist = 'retrypartial'; - } else { - $msg = &mt('Grade available'); - } - } - return &Apache::lonhtmlcommon::direct_parm_link($msg,$res->symb(),$parmlist,$part); + return &Apache::lonhtmlcommon::direct_parm_link(&mt("Answer available"),$res->symb(),'answerdate,duedate',$part); } if ($status == $res->EXCUSED) { return &mt("Excused by instructor"); @@ -959,31 +945,29 @@ sub render_resource { # links to open and close the folder my $whitespace = $location.'/whitespace_21.gif'; - my ($nomodal,$linkopen,$linkclose); - unless ($resource->is_map() || $params->{'resource_nolink'}) { - $linkopen = ""; - $linkclose = ""; - 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://})) { + 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; } - my $esclink = &js_escape($link); - if ($nomodal) { - $linkopen .= ""; - } else { - $linkopen .= ""; - } + } 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 .= ""; + $linkopen .= ""; } + } else { + $linkopen .= ""; } + my $linkclose = ""; # Default icon: unknown page my $icon = ""; @@ -1011,12 +995,8 @@ sub render_resource { if ($it->{CONDITION}) { $nowOpen = !$nowOpen; } - my $folderType; - if (&advancedUser() && $resource->is_missing_map()) { - $folderType = 'none'; - } else { - $folderType = $resource->is_sequence() ? 'folder' : 'page'; - } + + my $folderType = $resource->is_sequence() ? 'folder' : 'page'; my $title=$resource->title; $title=~s/\"/\&qout;/g; if (!$params->{'resource_no_folder_link'}) { @@ -1035,14 +1015,13 @@ sub render_resource { '&jump=' . &escape($resource->symb()) . "&folderManip=1\">"; - $linkclose = ''; + } else { # Don't allow users to manipulate folder $icon = "navmap.$folderType." . ($nowOpen ? 'closed' : 'open') . '.gif'; $icon = ""."\"".($nowOpen"; if ($params->{'caller'} eq 'sequence') { $linkopen = ""; - $linkclose = ''; } else { $linkopen = ""; $linkclose = ""; @@ -1061,30 +1040,10 @@ sub render_resource { } if ($params->{'mapHidden'} || $resource->randomout()) { $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->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()) { @@ -1209,7 +1168,7 @@ sub render_quick_status { my $linkclose = ""; $result .= ''; - if ($resource->is_gradable() && + if ($resource->is_problem() && !$firstDisplayed) { my $icon = $statusIconMap{$resource->simpleStatus($part)}; my $alt = $iconAltTags{$icon}; @@ -1234,7 +1193,7 @@ sub render_long_status { my $color; my $info = ''; - if ($resource->is_gradable() || $resource->is_practice()) { + if ($resource->is_problem() || $resource->is_practice()) { $color = $colormap{$resource->status}; if (dueInLessThan24Hours($resource, $part)) { @@ -1249,8 +1208,8 @@ sub render_long_status { } } - if (($resource->kind() eq "res") && - ($resource->is_raw_problem() || $resource->is_gradable()) && + if ($resource->kind() eq "res" && + $resource->is_raw_problem() && !$firstDisplayed) { if ($color) {$result .= ''; } $result .= getDescription($resource, $part); @@ -1297,7 +1256,7 @@ my @statuses = ($resObj->CORRECT, $resOb sub render_parts_summary_status { my ($resource, $part, $params) = @_; - if (!$resource->is_gradable() && !$resource->contains_problem) { return ''; } + if (!$resource->is_problem() && !$resource->contains_problem) { return ''; } if ($params->{showParts}) { return ''; } @@ -1409,49 +1368,15 @@ sub render { # an infinite loop my $oldFilterFunc = $filterFunc; $filterFunc = sub { my $res = shift; return !$res->randomout() && - ($res->deeplink($args->{'caller'}) ne 'absent') && - ($res->deeplink($args->{'caller'}) ne 'grades') && - !$res->deeplinkout() && &$oldFilterFunc($res);}; } my $condition = 0; if ($env{'form.condition'}) { $condition = 1; - } elsif (($env{'request.deeplink.login'}) && ($env{'request.course.id'}) && (!$userCanSeeHidden)) { - if (!defined($navmap)) { - $navmap = Apache::lonnavmaps::navmap->new(); - } - if (defined($navmap)) { - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $symb = &Apache::loncommon::symb_from_tinyurl($env{'request.deeplink.login'},$cnum,$cdom); - if ($symb) { - my $deeplink; - my $res = $navmap->getBySymb($symb); - if ($res->is_map()) { - my $mapname = &Apache::lonnet::declutter($res->src()); - $mapname = &Apache::lonnet::deversion($mapname); - $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink"); - } else { - $deeplink = $res->deeplink(); - } - if ($deeplink ne '') { - if ((split(/,/,$deeplink))[1] eq 'hide') { - if ($res->is_map()) { - map { $filterHash->{$_} = 1 if $_ } split(/,/,$res->map_hierarchy()); - } else { - my $mapurl = (&Apache::lonnet::decode_symb($symb))[0]; - my $map = $navmap->getResourceByUrl($mapurl); - map { $filterHash->{$_} = 1 if $_ } split(/,/,$map->map_hierarchy()); - } - } - } - } - } } - if (!$env{'form.folderManip'} && !defined($args->{'iterator'}) && !$args->{'nocurrloc'}) { + if (!$env{'form.folderManip'} && !defined($args->{'iterator'})) { # Step 1: Check to see if we have a navmap if (!defined($navmap)) { $navmap = Apache::lonnavmaps::navmap->new(); @@ -1658,22 +1583,16 @@ END } $result.=''; } - if (($args->{'caller'} eq 'navmapsdisplay') && ($env{'request.course.id'})) { + if (($args->{'caller'} eq 'navmapsdisplay') && + ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || + (&Apache::lonnet::allowed('cev',$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 + if ($env{'course.'.$env{'request.course.id'}.'.url'} eq "uploaded/$cdom/$cnum/default.sequence") { - if ((&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) || - (&Apache::lonnet::allowed('cev',$env{'request.course.id'}))) { - &add_linkitem($args->{'linkitems'},'edittoplevel', - "javascript:gocmd('/adm/coursedocs','editdocs');", - 'Content Editor'); - } - if ($counter) { - &add_linkitem($args->{'linkitems'},'printout', - "javascript:gopost('/adm/printout','/adm/navmaps');", - 'Prepare a printable document'); - } + &add_linkitem($args->{'linkitems'},'edittoplevel', + "javascript:gocmd('/adm/coursedocs','editdocs');", + 'Content Editor'); } } @@ -1719,32 +1638,12 @@ END # mark as hidden for users who have $userCanSeeHidden. # Use DFS for speed, since structure actually doesn't matter, # except what map has what resources. - # - # To ensure the "Selected Resources from selected folder in course" - # printout generation option will work in sessions launched via a - # deep link, the value of $args->{'filterFunc'} included in the - # call to lonnavmaps::render() is omitted from the filter function - # used with the DFS Iterator when $args->{'caller'} is 'printout'. - # - # As a result $sequence->{DATA}->{HAS_VISIBLE_CHILDREN} can be - # set to 1 for folder(s) which include resources only accessible - # for sessions launched via a deep link, when the current session - # is of that type. my $dfsit = Apache::lonnavmaps::DFSiterator->new($navmap, $it->{FIRST_RESOURCE}, $it->{FINISH_RESOURCE}, {}, undef, 1); - my $dfsFilterFunc; - if ($args->{'caller'} eq 'printout') { - $dfsFilterFunc = sub { my $res = shift; return !$res->randomout() && - ($res->deeplink($args->{'caller'}) ne 'absent') && - ($res->deeplink($args->{'caller'}) ne 'grades') && - !$res->deeplinkout();}; - } else { - $dfsFilterFunc = $filterFunc; - } my $depth = 0; $dfsit->next(); my $curRes = $dfsit->next(); @@ -1763,9 +1662,8 @@ END } 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 (&$dfsFilterFunc($curRes)) { + if (&$filterFunc($curRes)) { for my $sequence (@{$dfsit->getStack()}) { - next unless ($sequence->is_map()); $sequence->{DATA}->{HAS_VISIBLE_CHILDREN} = 1; } } @@ -1888,8 +1786,6 @@ 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; @@ -1902,22 +1798,6 @@ END } else { next; } - } elsif ($curRes->deeplinkout) { - if ($userCanSeeHidden) { - $args->{'mapHiddenDeepLink'} = 1; - } else { - next; - } - } else { - my $deeplink = $navmap->get_mapparam(undef,$mapname,"0.deeplink"); - my ($state,$others,$listed) = split(/,/,$deeplink); - if (($listed eq 'absent') || ($listed eq 'grades')) { - if ($userCanSeeHidden) { - $args->{'mapUnlisted'} = 1; - } else { - next; - } - } } } } @@ -1980,16 +1860,7 @@ END $args->{'condensed'} = 1; } } - } - # If deep-link parameter is set (and is not set to full) suppress link - # 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'}) eq 'full') || &advancedUser()) { - $args->{'resource_nolink'} = 0; - } else { - $args->{'resource_nolink'} = 1; - } + } # If the multipart problem was condensed, "forget" it was multipart if (scalar(@parts) == 1) { @@ -2142,7 +2013,7 @@ sub show_linkitems_toolbar { $result .= ''."\n". '