--- loncom/interface/lonnavmaps.pm 2025/05/28 13:42:14 1.509.2.14.2.12 +++ 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.12 2025/05/28 13:42:14 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 ''; } @@ -1366,17 +1325,13 @@ sub cmp_title { sub render { my $args = shift; &Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); + my $result = ''; # Configure the renderer. my $cols = $args->{'cols'}; if (!defined($cols)) { # no columns, no nav maps. return ''; } - my $legend = ''; - my $tools = ''; - my $result = ''; - my $tools_printed = 0; - my $tablestarted = 0; my $navmap; if (defined($args->{'navmap'})) { $navmap = $args->{'navmap'}; @@ -1413,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(); @@ -1588,24 +1509,24 @@ sub render { # Print key? if ($printKey) { - $legend = ''; - $legend .= ''; + $result .= '
Key:  
'; + $result.=''; my $location=&Apache::loncommon::lonhttpdurl("/adm/lonMisc"); if ($navmap->{LAST_CHECK}) { - $legend .= + $result .= ' '.&mt('New discussion since').' '. strftime("%A, %b %e at %I:%M %P", localtime($navmap->{LAST_CHECK})). ''; } else { - $legend .= ''; } - $legend .= '
Key:    '. ' '.&mt('New message (click to open)').'

'. '

  '. + $result .= '  '. ' '.&mt('Discussions').''. '   '.&mt('New message (click to open)'). '
'; + $result .= ''; } if ($printCloseAll && !$args->{'resource_no_folder_link'}) { @@ -1625,9 +1546,9 @@ sub render { "location.href='$link'",$text); } } else { - $tools = ''.&mt($text).''; + $result.= ''.&mt($text).''; } - $tools .= "\n"; + $result .= "\n"; } # Check for any unread discussions in all resources. @@ -1637,7 +1558,7 @@ sub render { 'Mark all posts read'); my $time=time; my $querystr = &HTML::Entities::encode($ENV{'QUERY_STRING'},'<>&"'); - $tools .= (< @@ -1654,43 +1575,45 @@ END } if ($totdisc > 0) { $haveDisc =~ s/:$//; - $tools .= (< END } } - $tools .= ''; + $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'); } } if ($args->{'caller'} eq 'navmapsdisplay') { - $tools .= &show_linkitems_toolbar($args,$condition); + $result .= &show_linkitems_toolbar($args,$condition); } elsif ($args->{'sort_html'}) { - $tools .= $args->{'sort_html'}; + $result.=$args->{'sort_html'}; } - #$tools .= "
\n"; + #$result .= "
\n"; + if ($r) { + $r->print($result); + $r->rflush(); + $result = ""; + } # End parameter setting + + $result .= "
\n"; # Data + $result.=&Apache::loncommon::start_data_table("LC_tableOfContent"); my $res = "Apache::lonnavmaps::resource"; my %condenseStatuses = @@ -1702,8 +1625,7 @@ END $args->{'counter'} = 0; # counts the rows $args->{'indentLevel'} = 0; $args->{'isNewBranch'} = 0; - $args->{'condensed'} = 0; - $args->{'deeplinknolist'} = 0; + $args->{'condensed'} = 0; my $location = &Apache::loncommon::lonhttpdurl("/adm/lonIcons/whitespace_21.gif"); $args->{'indentString'} = setDefault($args->{'indentString'}, ""); @@ -1716,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(); @@ -1760,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; } } @@ -1879,17 +1780,12 @@ END # If this has been filtered out, continue on if (!(&$filterFunc($curRes))) { - if (!$userCanSeeHidden && !$curRes->randomout && $curRes->deeplinkout) { - $args->{'deeplinknolist'} ++; - } $args->{'isNewBranch'} = 0; # Don't falsely remember this next; } # 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,24 +1798,6 @@ END } else { next; } - } elsif ($curRes->deeplinkout) { - if ($userCanSeeHidden) { - $args->{'mapHiddenDeepLink'} = 1; - } else { - $args->{'deeplinknolist'} ++; - 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 { - $args->{'deeplinknolist'} ++; - next; - } - } } } } @@ -1930,10 +1808,6 @@ END } $args->{'counter'}++; - unless ($tablestarted) { - $result .= "
\n".&Apache::loncommon::start_data_table("LC_tableOfContent"); - $tablestarted = 1; - } # Does it have multiple parts? $args->{'multipart'} = 0; @@ -1986,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) { @@ -2084,12 +1949,6 @@ END } if ($r && $rownum % 20 == 0) { - unless ($tools_printed) { - $r->print($legend.$tools); - $legend = ""; - $tools = ""; - $tools_printed = 1; - } $r->print($result); $result = ""; $r->rflush(); @@ -2105,10 +1964,8 @@ END } } - if ($tablestarted) { - $result.=&Apache::loncommon::end_data_table(); - } - + $result.=&Apache::loncommon::end_data_table(); + # Print out the part that jumps to #curloc if it exists # delay needed because the browser is processing the jump before # it finishes rendering, so it goes to the wrong place! @@ -2125,23 +1982,12 @@ if (location.href.indexOf('#curloc')==-1 } if ($r) { - unless ($tools_printed) { - if (($args->{'counter'}) || ($userCanSeeHidden) || - (($args->{'caller'} eq 'navmapsdisplay') && - ($env{'form.showOnlyHomework'} || - $ENV{QUERY_STRING} =~ /^jumpToFirstHomework/))) { - $r->print($legend.$tools); - } - $legend = ""; - $tools = ""; - $tools_printed = 1; - } $r->print($result); $result = ""; $r->rflush(); } - return $legend.$tools.$result; + return $result; } sub add_linkitem { @@ -2167,7 +2013,7 @@ sub show_linkitems_toolbar { $result .= ''."\n". '
    '; my @linkorder = ('firsthomework','everything','uncompleted', - 'changefolder','clearbubbles','printout','edittoplevel'); + 'changefolder','clearbubbles','edittoplevel'); foreach my $link (@linkorder) { if (ref($args->{'linkitems'}{$link}) eq 'HASH') { if ($args->{'linkitems'}{$link}{'text'} ne '') { @@ -2299,17 +2145,10 @@ sub new { $self->{USERNAME} = shift || $env{'user.name'}; $self->{DOMAIN} = shift || $env{'user.domain'}; - $self->{SECTION} = shift; $self->{CODE} = shift; - $self->{NOHIDE} = shift; + $self->{NOHIDE} = shift; - if (($self->{SECTION} eq '') && ($env{'request.course.sec'} ne '')) { - if (($self->{USERNAME} eq $env{'user.name'}) && - ($self->{USERNAME} eq $env{'user.domain'})) { - $self->{SECTION} = $env{'request.course.sec'}; - } - } # Resource cache stores navmap resources as we reference them. We generate # them on-demand so we don't pay for creating resources unless we use them. @@ -2351,7 +2190,7 @@ sub new { $self->{PARM_HASH} = \%parmhash; $self->{PARM_CACHE} = {}; } else { - $self->change_user($self->{USERNAME}, $self->{DOMAIN}, $self->{SECTION}, $self->{CODE}, $self->{NOHIDE}); + $self->change_user($self->{USERNAME}, $self->{DOMAIN}, $self->{CODE}, $self->{NOHIDE}); } return $self; @@ -2362,17 +2201,15 @@ sub new { # username/domain associated with a navmap (e.g. to navigate for someone # else besides the current user...if sufficiently privileged. # Parameters: -# user - New user. -# domain - Domain to which the user belongs. -# section - Section to which the user belongs. -# code - Anonymous CODE in use. +# user - New user. +# domain- Domain the user belongs to. +# code - Anonymous CODE in use. # Implicit inputs: # sub change_user { my $self = shift; $self->{USERNAME} = shift; $self->{DOMAIN} = shift; - $self->{SECTION} = shift; $self->{CODE} = shift; $self->{NOHIDE} = shift; @@ -2589,7 +2426,7 @@ sub getIterator { my $self = shift; my $iterator = Apache::lonnavmaps::iterator->new($self, shift, shift, shift, undef, shift, - shift, shift, shift); + shift, shift); return $iterator; } @@ -2878,7 +2715,7 @@ sub parmval_real { $self->generate_course_user_opt(); my $cid=$env{'request.course.id'}; - my $csec=$self->{SECTION}; + my $csec=$env{'request.course.sec'}; my $cgroup=''; my @cgrps=split(/:/,$env{'request.course.groups'}); if (@cgrps > 0) { @@ -2893,10 +2730,6 @@ sub parmval_real { my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb); $mapname = &Apache::lonnet::deversion($mapname); - my $toolsymb = ''; - if ($fn =~ /ext\.tool$/) { - $toolsymb = $symb; - } # ----------------------------------------------------- Cascading lookup scheme my $rwhat=$what; $what=~s/^parameter\_//; @@ -2960,9 +2793,9 @@ sub parmval_real { my $meta_rwhat=$rwhat; $meta_rwhat=~s/\./_/g; - my $default=&Apache::lonnet::metadata($fn,$meta_rwhat,$toolsymb); + my $default=&Apache::lonnet::metadata($fn,$meta_rwhat); if (defined($default)) { return [$default,'resource']} - $default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat,$toolsymb); + $default=&Apache::lonnet::metadata($fn,'parameter_'.$meta_rwhat); if (defined($default)) { return [$default,'resource']} # --------------------------------------------------- fifth, check more course if (defined($courseopt)) { @@ -2985,13 +2818,13 @@ sub parmval_real { if (defined($partgeneral[0])) { return \@partgeneral; } } if ($recurse) { return []; } - my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat,$toolsymb); + my $pack_def=&Apache::lonnet::packages_tab_default($fn,'resource.'.$rwhat); if (defined($pack_def)) { return [$pack_def,'resource']; } return ['']; } sub recurseup_maps { - my ($self,$mapname,$getsymb) = @_; + my ($self,$mapname) = @_; my @recurseup; if ($mapname) { my $res = $self->getResourceByUrl($mapname); @@ -2999,11 +2832,7 @@ sub recurseup_maps { my @pcs = split(/,/,$res->map_hierarchy()); shift(@pcs); if (@pcs) { - if ($getsymb) { - @recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->symb()); } reverse(@pcs); - } else { - @recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); - } + @recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs); } } } @@ -3035,12 +2864,8 @@ sub recursed_crumbs { my $pc = $map->map_pc(); next if ((!$pc) || ($pc == 1)); push(@links,$map); - my $text = $map->title(); - if ($text eq '') { - $text = '...'; - } - push(@revmapinfo,{'href' => $env{'request.use_absolute'}.$map->link().'?navmap=1','text' => $text,'no_mt' => 1,}); - $totallength += length($text); + 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) { @@ -3052,11 +2877,7 @@ sub recursed_crumbs { } @revmapinfo = (); foreach my $map (@links) { - my $title = $map->title(); - if ($title eq '') { - $title = '...'; - } - my $showntitle = &truncate_crumb_text($title,$avg); + 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,}); } @@ -3131,7 +2952,7 @@ sub get_mapparam { # Get the course id and section if there is one. my $cid=$env{'request.course.id'}; - my $csec=$self->{SECTION}; + my $csec=$env{'request.course.sec'}; my $cgroup=''; my @cgrps=split(/:/,$env{'request.course.groups'}); if (@cgrps > 0) { @@ -3300,11 +3121,11 @@ sub getcourseparam { my $uname = $self->{USERNAME}; my $udom = $self->{DOMAIN}; - my $csec = $self->{SECTION}; - # Course and group ids come from the env: + # Course, section, group ids come from the env: my $cid = $env{'request.course.id'}; + my $csec = $env{'request.course.sec'}; my $cgroup = ''; # Assume no group my @cgroups = split(/:/, $env{'request.course.groups'}); @@ -3541,71 +3362,6 @@ sub usedVersion { return $self->navhash("version_$linkurl"); } -sub isFirstResource { - my $self = shift; - my $map = shift; - my $symb = shift; - return unless (ref($map)); - my $isfirst; - my $firstResource = $map->map_start(); - if (ref($firstResource)) { - if ((!$firstResource->is_map()) && ($firstResource->src() ne '')) { - if ($firstResource->symb() eq $symb) { - $isfirst = 1; - } else { - $isfirst = 0; - } - } else { - my $it = $self->getIterator($firstResource,undef,undef,1); - while ( my $res=$it->next()) { - if ((ref($res)) && ($res->src() ne '') && (!$res->is_map())) { - if ($res->symb() eq $symb) { - $isfirst = 1; - } else { - $isfirst = 0; - } - last; - } - } - } - } - return $isfirst; -} - -sub isLastResource { - my $self = shift; - my $map = shift; - my $symb = shift; - return unless (ref($map)); - my $islast; - my $lastResource = $map->map_finish(); - if (ref($lastResource)) { - if ((!$lastResource->is_map()) && ($lastResource->src() ne '')) { - if ($lastResource->symb() eq $symb) { - $islast = 1; - } else { - $islast = 0; - } - } else { - my $currRes = $self->getBySymb($symb); - if (ref($currRes)) { - my $it = $self->getIterator($currRes,undef,undef,1); - while ( my $res=$it->next()) { - if ((ref($res)) && ($res->src() ne '') && (!$res->is_map())) { - if ($res->symb() eq $symb) { - $islast = 1; - } else { - $islast = 0; - } - last; - } - } - } - } - } - return $islast; -} - 1; package Apache::lonnavmaps::iterator; @@ -3636,7 +3392,7 @@ getIterator behaves as follows: =over 4 -=item * B(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap, $deeplinklisted): +=item * B(firstResource, finishResource, filterHash, condition, forceTop, returnTopMap): All parameters are optional. firstResource is a resource reference corresponding to where the iterator should start. It defaults to @@ -3653,10 +3409,7 @@ 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. 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(). +before anything else. 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 @@ -3793,10 +3546,6 @@ 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. @@ -3888,8 +3637,7 @@ sub new { $finishResource, $self->{FILTER}, $self->{ALREADY_SEEN}, $self->{CONDITION}, - $self->{FORCE_TOP}, - undef,$self->{DEEPLINKLISTED}); + $self->{FORCE_TOP}); } # Set up some bookkeeping information. @@ -4059,14 +3807,13 @@ sub next { $finishResource, $self->{FILTER}, $self->{ALREADY_SEEN}, $self->{CONDITION}, - $self->{FORCE_TOP}, - undef,$self->{DEEPLINKLISTED}); + $self->{FORCE_TOP}); } # 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,$self->{DEEPLINKLISTED}); + my $browsePriv = $self->{HERE}->browsePriv($noblockcheck); if (!$self->{HERE}->src() || (!($browsePriv eq 'F') && !($browsePriv eq '2')) ) { return $self->next($closeAllPages); @@ -4494,7 +4241,6 @@ 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'); @@ -4663,19 +4409,6 @@ sub is_problem { } return 0; } -sub is_tool { - my $self=shift; - my $src = $self->src(); - return ($src =~ /ext\.tool$/); -} -sub is_gradable { - my $self=shift; - my $src = $self->src(); - if (($src =~ /$LONCAPA::assess_re/) || - (($self->is_tool()) && ($self->parmval('gradable',0) =~ /^yes$/i))) { - return !($self->is_practice()); - } -} # # The has below is the set of status that are considered 'incomplete' # @@ -4734,11 +4467,6 @@ sub is_sequence { return $self->navHash("is_map_", 1) && $self->navHash("map_type_" . $self->map_pc()) eq 'sequence'; } -sub is_missing_map { - my $self=shift; - return $self->navHash("is_map_", 1) && - $self->navHash("map_type_" . $self->map_pc()) eq 'none'; -} sub is_survey { my $self = shift(); my $part = shift(); @@ -4768,6 +4496,7 @@ 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()); } @@ -5088,12 +4817,11 @@ sub duedate { my $date; my @interval=$self->parmval("interval", $part); my $due_date=$self->parmval("duedate", $part); - if ($interval[0] =~ /(\d+)/) { - my $timelimit = $1; - my $first_access=&Apache::lonnet::get_first_access($interval[1], + if ($interval[0] =~ /\d+/) { + my $first_access=&Apache::lonnet::get_first_access($interval[1], $self->{SYMB}); if (defined($first_access)) { - my $interval = $first_access+$timelimit; + my $interval = $first_access+$interval[0]; $date = (!$due_date || $interval < $due_date) ? $interval : $due_date; } else { @@ -5166,7 +4894,7 @@ sub weight { my $weight = &Apache::lonnet::EXT('resource.'.$part.'.weight', $self->{SYMB}, $self->{DOMAIN}, $self->{USERNAME}, - $self->{SECTION}); + $env{'request.course.sec'}); return $weight; } sub part_display { @@ -5187,46 +4915,6 @@ 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 { @@ -5375,8 +5063,6 @@ sub parts { my $self = shift; if ($self->ext) { return []; } - if (($self->is_tool()) && - ($self->is_gradable())) { return ['0']; } $self->extractParts(); return $self->{PARTS}; @@ -5467,7 +5153,7 @@ sub extractParts { my %parts; # Retrieve part count, if this is a problem - if ($self->is_raw_problem()) { + if ($self->is_problem()) { my $partorder = &Apache::lonnet::metadata($self->src(), 'partorder'); my $metadata = &Apache::lonnet::metadata($self->src(), 'packages'); @@ -5634,6 +5320,7 @@ The problem will be opened later. Open and not yet due. + =item * B: The due date has passed, but the answer date has not yet arrived. @@ -5646,26 +5333,6 @@ The due date has passed and there is no The answer date is here. -=item * B: - -No dates have been set for this problem at all. - -=item * B: - -The due date has passed, feedback is suppressed, the problem was attempted, and the answer date has not yet arrived. - -=item * B: - -The due date has passed, feedback is suppressed, the problem was attempted, and there is no answer opening date set. - -=item * B: - -The due date has passed, feedback is suppressed, the problem was not attempted, and the answer date has not yet arrived. - -=item * B: - -The due date has passed, feedback is suppressed, the problem was not attempted, and there is no answer opening date set. - =item * B: The information is unknown due to network failure. @@ -5681,10 +5348,6 @@ sub PAST_DUE_NO_ANSWER { return 2; } sub PAST_DUE_ANSWER_LATER { return 3; } sub ANSWER_OPEN { return 4; } sub NOTHING_SET { return 5; } -sub PAST_DUE_ATMPT_ANS { return 6; } -sub PAST_DUE_ATMPT_NOANS { return 7; } -sub PAST_DUE_NO_ATMT_ANS { return 8; } -sub PAST_DUE_NO_ATMT_NOANS { return 9; } sub NETWORK_FAILURE { return 100; } # getDateStatus gets the date status for a given problem part. @@ -5774,14 +5437,6 @@ Attempted, and not yet graded. Attempted, and credit received for attempt (survey and anonymous survey only). -=item * B: - -Attempted, but wrong for LTI Tool Provider by passback of grade - -=item * B: - -Correct for LTI Tool Provider by passback of grade - =back =cut @@ -5794,8 +5449,6 @@ sub CORRECT_BY_OVERRIDE { return 14; } sub EXCUSED { return 15; } sub ATTEMPTED { return 16; } sub CREDIT_ATTEMPTED { return 17; } -sub INCORRECT_BY_PASSBACK { return 18; } -sub CORRECT_BY_PASSBACK { return 19; } sub getCompletionStatus { my $self = shift; @@ -5810,12 +5463,8 @@ sub getCompletionStatus { if ($status eq 'correct_by_override') { return $self->CORRECT_BY_OVERRIDE; } - if ($status eq 'correct_by_passback') { - return $self->CORRECT_BY_PASSBACK; - } if ($status eq 'incorrect_attempted') {return $self->INCORRECT; } if ($status eq 'incorrect_by_override') {return $self->INCORRECT_BY_OVERRIDE; } - if ($status eq 'incorrect_by_passback') {return $self->INCORRECT_BY_PASSBACK; } if ($status eq 'excused') {return $self->EXCUSED; } if ($status eq 'ungraded_attempted') {return $self->ATTEMPTED; } if ($status eq 'credit_attempted') { @@ -5888,26 +5537,6 @@ set. The problem is past due, not considered correct, and an answer date in the future is set. -=item * B: - -The problem is past due, feedback is suppressed, the problem was -attempted and an answer date in the future is set. - -=item * B: - -The problem is past due, feedback is suppressed, the problem was -attempted and no answer date is set. - -=item * B: - -The problem is past due, feedback is suppressed, the problem was -not attempted and an answer date in the future is set. - -=item * B: - -The problem is past due, feedback is suppressed, the problem was -not attempted and no answer date is set. - =item * B: The problem is past due, not correct, and the answer is now available. @@ -5989,20 +5618,8 @@ sub status { # There are a few whole rows we can dispose of: if ($completionStatus == CORRECT || - $completionStatus == CORRECT_BY_OVERRIDE || - $completionStatus == CORRECT_BY_PASSBACK ) { - if ( $suppressFeedback ) { - if ($dateStatus == PAST_DUE_ANSWER_LATER || - $dateStatus == PAST_DUE_NO_ANSWER ) { - if ($dateStatus == PAST_DUE_ANSWER_LATER) { - return PAST_DUE_ATMPT_ANS; - } else { - return PAST_DUE_ATMPT_NOANS; - } - } else { - return ANSWER_SUBMITTED; - } - } + $completionStatus == CORRECT_BY_OVERRIDE ) { + if ( $suppressFeedback ) { return ANSWER_SUBMITTED } my $awarded=$self->awarded($part); if ($awarded < 1 && $awarded > 0) { return PARTIALLY_CORRECT; @@ -6014,8 +5631,7 @@ sub status { # If it's WRONG... and not open if ( ($completionStatus == INCORRECT || - $completionStatus == INCORRECT_BY_OVERRIDE || - $completionStatus == INCORRECT_BY_PASSBACK) + $completionStatus == INCORRECT_BY_OVERRIDE) && (!$self->opendate($part) || $self->opendate($part) > time()) ) { return INCORRECT; } @@ -6042,23 +5658,7 @@ sub status { if ($dateStatus == PAST_DUE_ANSWER_LATER || $dateStatus == PAST_DUE_NO_ANSWER ) { - if ($suppressFeedback) { - if ($completionStatus == NOT_ATTEMPTED) { - if ($dateStatus == PAST_DUE_ANSWER_LATER) { - return PAST_DUE_NO_ATMT_ANS; - } else { - return PAST_DUE_NO_ATMT_NOANS; - } - } else { - if ($dateStatus == PAST_DUE_ANSWER_LATER) { - return PAST_DUE_ATMPT_ANS; - } else { - return PAST_DUE_ATMPT_NOANS; - } - } - } else { - return $dateStatus; - } + return $suppressFeedback ? ANSWER_SUBMITTED : $dateStatus; } if ($dateStatus == ANSWER_OPEN) { @@ -6073,8 +5673,7 @@ sub status { } # If it's WRONG... - if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE || - $completionStatus == INCORRECT_BY_PASSBACK) { + if ($completionStatus == INCORRECT || $completionStatus == INCORRECT_BY_OVERRIDE) { # and there are TRIES LEFT: if ($self->tries($part) < $self->maxtries($part) || !$self->maxtries($part)) { return $suppressFeedback ? ANSWER_SUBMITTED : TRIES_LEFT; @@ -6269,10 +5868,6 @@ my %compositeToSimple = EXCUSED() => CORRECT, PAST_DUE_NO_ANSWER() => INCORRECT, PAST_DUE_ANSWER_LATER() => INCORRECT, - PAST_DUE_ATMPT_ANS() => ATTEMPTED, - PAST_DUE_ATMPT_NOANS() => ATTEMPTED, - PAST_DUE_NO_ATMT_ANS() => CLOSED, - PAST_DUE_NO_ATMT_NOANS() => CLOSED, ANSWER_OPEN() => INCORRECT, OPEN_LATER() => CLOSED, TRIES_LEFT() => OPEN, @@ -6451,23 +6046,13 @@ 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,$nodeeplinkcheck, - $nodeeplinkout); + undef,$noblockcheck); } =pod