--- loncom/interface/lonmenu.pm 2023/01/23 05:40:00 1.369.2.83.2.7 +++ loncom/interface/lonmenu.pm 2023/07/06 19:16:16 1.369.2.83.2.8 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines to control the menu # -# $Id: lonmenu.pm,v 1.369.2.83.2.7 2023/01/23 05:40:00 raeburn Exp $ +# $Id: lonmenu.pm,v 1.369.2.83.2.8 2023/07/06 19:16:16 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -267,7 +267,7 @@ sub prep_menuitem { # entries from mydesk.tab sub primary_menu { my ($crstype,$ltimenu,$menucoll,$menuref,$links_disabled,$links_target) = @_; - my (%menu,%menuopts); + my (%menu,%ltiexc,%menuopts); # each element of @primary contains following array: # (link url, icon path, alt text, link text, condition, position) my $public; @@ -275,6 +275,17 @@ sub primary_menu { || (($env{'user.name'} eq '') && ($env{'user.domain'} eq ''))) { $public = 1; } + my $lti; + if ($env{'request.lti.login'}) { + $lti = 1; + if (ref($ltimenu) eq 'HASH') { + foreach my $item ('fullname','logout') { + unless ($ltimenu->{$item}) { + $ltiexc{$item} = 1; + } + } + } + } my ($listclass,$linkattr,$target); if ($links_disabled) { $listclass = 'LCisDisabled'; @@ -283,11 +294,14 @@ sub primary_menu { if ($links_target ne '') { $target = $links_target; } else { - my $deeplinktarget; + my ($ltitarget,$deeplinktarget); + if ($env{'request.lti.login'}) { + $ltitarget = $env{'request.lti.target'}; + } if ($env{'request.deeplink.login'}) { $deeplinktarget = $env{'request.deeplink.target'}; } - if ($deeplinktarget eq '_self') { + if (($ltitarget eq 'iframe') || ($deeplinktarget eq '_self')) { $target = '_self'; } else { $target = '_top'; @@ -310,10 +324,15 @@ sub primary_menu { && !$public; # only visible to public # users next if $$menuitem[4] eq 'roles' ##show links depending on - && &Apache::loncommon::show_course(); ##term 'Courses' or - next if $$menuitem[4] eq 'courses' ##'Roles' wanted - && !&Apache::loncommon::show_course(); ## - + && (&Apache::loncommon::show_course() ##term 'Courses' or + || $lti); ##'Roles' wanted + next if $$menuitem[4] eq 'courses' ##and not LTI access + && (!&Apache::loncommon::show_course() + || $lti); + next if $$menuitem[4] eq 'notlti' + && $lti; + next if $$menuitem[4] eq 'ltiexc' + && exists($ltiexc{lc($menuitem->[3])}); my $title = $menuitem->[3]; my $position = $menuitem->[5]; if ($position eq '') { @@ -322,7 +341,7 @@ sub primary_menu { if ($env{'request.course.id'} && $menucoll) { if (($menuitem->[6]) && (!$menuopts{$menuitem->[6]})) { if ($menuitem->[6] eq 'pers') { - if ($menuopts{'name'} && + if ($menuopts{'name'} && !$ltiexc{'fullname'} && $env{'user.name'} && $env{'user.domain'}) { $menu{$position} .= '
  • '. &Apache::loncommon::plainname($env{'user.name'}, @@ -357,7 +376,7 @@ sub primary_menu { push(@primsub,$item); } if ($title eq 'Personal') { - if ($env{'user.name'} && $env{'user.domain'}) { + if ($env{'user.name'} && $env{'user.domain'} && !$ltiexc{'fullname'}) { unless (($env{'request.course.id'}) && ($menucoll) && (!$menuopts{'name'})) { $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); } @@ -464,7 +483,8 @@ sub secondary_menu { my $canplc = &Apache::lonnet::allowed('plc', $crs_sec); my $author = &getauthor(); - my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools,%menuopts); + my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools, + $lti,$ltimapres,%ltiexc,%menuopts); $grouptools = 0; if ($env{'request.course.id'}) { $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; @@ -498,6 +518,19 @@ sub secondary_menu { } } } + if ($env{'request.lti.login'}) { + $lti = 1; + if (ref($ltimenu) eq 'HASH') { + foreach my $item ('fullname','coursetitle','role','logout','grades') { + unless ($ltimenu->{$item}) { + $ltiexc{$item} = 1; + } + } + } + if (($ltiscope eq 'map') || ($ltiscope eq 'resource')) { + $ltimapres = 1; + } + } } if (($menucoll) && (ref($menuref) eq 'HASH')) { %menuopts = %{$menuref}; @@ -522,11 +555,14 @@ sub secondary_menu { if ($links_target ne '') { $target = $links_target; } else { - my $deeplinktarget; + my ($ltitarget,$deeplinktarget); + if ($env{'request.lti.login'}) { + $ltitarget = $env{'request.lti.target'}; + } if ($env{'request.deeplink.login'}) { $deeplinktarget = $env{'request.deeplink.target'}; } - if ($deeplinktarget eq '_self') { + if (($ltitarget eq 'iframe') || ($deeplinktarget eq '_self')) { $target = '_self'; } else { $target = '_top'; @@ -546,7 +582,7 @@ sub secondary_menu { next if $$menuitem[4] eq 'crseditCommunity' && ($crstype eq 'Course'); next if $$menuitem[4] eq 'nvgr' - && $canvgr; + && ($canvgr || $ltiexc{'grades'}); next if $$menuitem[4] eq 'vgr' && !$canvgr; next if $$menuitem[4] eq 'viewusers' @@ -573,6 +609,14 @@ sub secondary_menu { && !$author; next if $$menuitem[4] eq 'cca' && !$canmodifycoauthor; + next if $$menuitem[4] eq 'notltimapres' + && $ltimapres; + next if $$menuitem[4] eq 'notlti' + && $lti; + next if $$menuitem[4] eq 'lti' + && (!$lti || !$noprimary); + next if $$menuitem[3] eq 'Logout' + && $ltiexc{'logout'}; my $title = $menuitem->[3]; if ($env{'request.course.id'} && $menucoll) { @@ -603,9 +647,21 @@ sub secondary_menu { next if ($item->[2] eq 'params' && !$canmodpara && !$canviewpara); next if ($item->[2] eq 'author' && !$author); next if ($item->[2] eq 'cca' && !$canmodifycoauthor); + next if ($item->[2] eq 'lti' && !$lti); + if ($item->[2] =~ /^lti(portfolio|wishlist|blog)$/) { + my $tool = $1; + next if !$lti; + next if (!&Apache::lonnet::usertools_access('','',$tool, + undef,'tools')); + } push(@scndsub,$item); } } + if ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'}) { + unless ($ltiexc{'fullname'}) { + $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); + } + } if (@scndsub > 0) { $menu .= &create_submenu($link,$target,&mt($title),\@scndsub,1,undef, $listclass,$linkattr); @@ -864,26 +920,33 @@ sub innerregister { my $restitle = &Apache::lonnet::gettitle($symb); my (@crumbs,@mapcrumbs); - if (($env{'request.noversionuri'} ne '/adm/navmaps') && ($mapurl ne '') && - ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'})) { - $navmap = Apache::lonnavmaps::navmap->new(); - if (ref($navmap)) { - @mapcrumbs = $navmap->recursed_crumbs($mapurl,$restitle); + if (($env{'request.noversionuri'} ne '/adm/navmaps') && ($mapurl ne '')) { + unless ($ltiscope eq 'resource') { + if (($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) && + !(($ltiscope eq 'map') && (&Apache::lonnet::clutter($resurl) eq $ltiuri))) { + $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + @mapcrumbs = $navmap->recursed_crumbs($mapurl,$restitle); + } + } } } - @crumbs = ({text => $crstype.' Contents', - href => "Javascript:gopost('/adm/navmaps','')"}); + unless (($ltiscope eq 'map') || ($ltiscope eq 'resource')) { + @crumbs = ({text => $crstype.' Contents', + href => "Javascript:gopost('/adm/navmaps','')"}); + } if ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) { if (@mapcrumbs) { push(@crumbs,@mapcrumbs); - } else { + } elsif (($ltiscope ne 'map') && ($ltiscope ne 'resource')) { push(@crumbs, {text => '...', no_mt => 1}); } } unless ((@mapcrumbs) || (!$maptitle) || ($maptitle eq 'default.sequence') || - ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'})) { + ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) || + ($ltiscope eq 'resource')) { push @crumbs, {text => $maptitle, no_mt => 1, href => &Apache::lonnet::clutter($mapurl).'?navmap=1'}; } @@ -996,8 +1059,14 @@ sub innerregister { $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'}); $perms{'cev'} = &Apache::lonnet::allowed('cev',$env{'request.course.id'}); my @privs; + my $gradable_exttool; if ($env{'request.symb'} ne '') { - if ($env{'request.filename'}=~/$LONCAPA::assess_re/) { + if ($env{'request.noversionuri'} =~ m{^/adm/$cdom/$cnum/(\d+)/ext\.tool$}) { + if (&Apache::lonnet::EXT('resource.0.gradable') =~ /^yes$/i) { + $gradable_exttool = 1; + push(@privs,('mgr','vgr')); + } + } elsif ($env{'request.filename'}=~/$LONCAPA::assess_re/) { push(@privs,('mgr','vgr')); } push(@privs,('opa','vpa')); @@ -1098,13 +1167,42 @@ ENDMENUITEMS # We are in a course and looking at a registered URL # Should probably be in mydesk.tab # - - $menuitems=(<new(); + if (ref($navmap)) { + my $mapres = $navmap->getResourceByUrl($ltiuri); + if (ref($mapres)) { + if ($navmap->isLastResource($mapres,$env{'request.symb'})) { + $showforw = 0; + } + if ($navmap->isFirstResource($mapres,$env{'request.symb'})) { + $showback = 0; + } + } + } + if ($showback) { + $menuitems.=" +s&2&1&back.png&&&gopost('/adm/flip','back:'+currentURL)&Previous content resource&&1"; + } + if ($showforw) { + $menuitems.=" +s&2&3&forw.png&&&gopost('/adm/flip','forward:'+currentURL)&Next content resource&&3"; + } + } else { + $menuitems.=" +s&2&1&back.png&&&gopost('/adm/flip','back:'+currentURL)&Previous content resource&&1 +s&2&3&forw.png&&&gopost('/adm/flip','forward:'+currentURL)&Next content resource&&3"; + } + $menuitems .= (<'.$pic.''; @@ -2593,7 +2692,10 @@ sub utilityfunctions { my $countdown = &countdown_toggle_js(); - my $deeplinktarget; + my ($ltitarget,$deeplinktarget); + if ($env{'request.lti.login'}) { + $ltitarget = $env{'request.lti.target'}; + } if ($env{'request.deeplink.login'}) { $deeplinktarget = $env{'request.deeplink.target'}; } @@ -2698,8 +2800,9 @@ function golist(url) { currentURL = null; currentSymb= null; var lcHostname = setLCHost(); + var ltitarget = '$ltitarget'; var deeplinktarget = '$deeplinktarget'; - if (deeplinktarget == '_self') { + if ((ltitarget == 'iframe') || (deeplinktarget == '_self')) { document.location.href=lcHostname+url; } else { top.location.href=lcHostname+url; @@ -2761,6 +2864,17 @@ function open_source() { 'height=500,width=600,resizable=yes,location=no,menubar=no,toolbar=no,scrollbars=yes'); } +function open_aboutLC() { + var isMobile = "$env{'browser.mobile'}"; + var url = '/adm/about.html'; + if (isMobile == 1) { + openMyModal(url,600,400,'yes'); + } else { + window.open(url,"aboutLONCAPA","height=400,width=600,scrollbars=1,resizable=1,menubar=0,location=1"); + } + return; +} + (function (\$) { \$(document).ready(function () { \$.single=function(a){return function(b){a[0]=b;return a}}(\$([1])); @@ -2804,7 +2918,8 @@ sub constspaceform { $target = ' target="_parent"'; $printtarget = ' target="_parent"'; } else { - unless (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self')) { + unless ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) || + (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) { $target = ' target="_top"'; $printtarget = ' target="_top"'; } @@ -3381,16 +3496,26 @@ sub required_privs { sub countdown_timer { if (($env{'request.course.id'}) && ($env{'request.symb'} ne '') && - ($env{'request.filename'}=~/$LONCAPA::assess_re/)) { + (($env{'request.filename'}=~/$LONCAPA::assess_re/) || + (($env{'request.symb'} =~ /ext\.tool$/) && + (&Apache::lonnet::EXT('resource.0.gradable',$env{'request.symb'}) =~ /^yes$/i)))) { my ($type,$hastimeleft,$slothastime); my $now = time; if ($env{'request.filename'} =~ /\.task$/) { $type = 'Task'; + } elsif ($env{'request.symb'} =~ /ext\.tool$/) { + $type = 'tool'; } else { $type = 'problem'; } - my ($status,$accessmsg,$slot_name,$slot) = - &Apache::lonhomework::check_slot_access('0',$type); + my ($status,$accessmsg,$slot_name,$slot); + if ($type eq 'tool') { + ($status,$accessmsg,$slot_name,$slot) = + &Apache::lonhomework::check_slot_access('0',$type,$env{'request.symb'},['0']); + } else { + ($status,$accessmsg,$slot_name,$slot) = + &Apache::lonhomework::check_slot_access('0',$type); + } if ($slot_name ne '') { if (ref($slot) eq 'HASH') { if (($slot->{'starttime'} < $now) &&