--- loncom/interface/lonmenu.pm 2023/01/23 05:40:00 1.369.2.83.2.7
+++ loncom/interface/lonmenu.pm 2023/09/02 15:56:34 1.369.2.83.2.9
@@ -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.9 2023/09/02 15:56:34 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'));
@@ -1012,8 +1081,8 @@ sub innerregister {
#
# Determine whether or not to show Grades and Submissions buttons
#
- if ($env{'request.symb'} ne '' &&
- $env{'request.filename'}=~/$LONCAPA::assess_re/) {
+ if (($env{'request.symb'} ne '') &&
+ (($env{'request.filename'}=~/$LONCAPA::assess_re/) || ($gradable_exttool))) {
if ($perms{'mgr'}) {
$hwkadd.= &switch('','',7,2,'pgrd.png','Content Grades',
'grades[_4]',
@@ -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 .= (<';
@@ -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) &&