--- loncom/interface/lonmenu.pm 2020/07/19 00:24:36 1.369.2.79.2.2 +++ loncom/interface/lonmenu.pm 2022/01/03 16:37:24 1.369.2.83.2.1 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines to control the menu # -# $Id: lonmenu.pm,v 1.369.2.79.2.2 2020/07/19 00:24:36 raeburn Exp $ +# $Id: lonmenu.pm,v 1.369.2.83.2.1 2022/01/03 16:37:24 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -240,7 +240,7 @@ use vars qw(@desklines %category_names % my @inlineremote; sub prep_menuitem { - my ($menuitem) = @_; + my ($menuitem,$listclass,$linkattr) = @_; return '' unless(ref($menuitem) eq 'ARRAY'); my $link; if ($$menuitem[1]) { # graphical Link @@ -250,10 +250,10 @@ sub prep_menuitem { } else { # textual Link $link = &mt($$menuitem[3]); } - return '
  • ':'
  • ').'$link
  • |; + . qq| href="$$menuitem[0]" target="_top" $linkattr>$link|; } # primary_menu() evaluates @primary_menu and returns a two item array, @@ -263,7 +263,8 @@ sub prep_menuitem { # @primary_menu is filled within the BEGIN block of this module with # entries from mydesk.tab sub primary_menu { - my %menu; + my ($crstype,$ltimenu,$menucoll,$menuref,$links_disabled) = @_; + my (%menu,%menuopts); # each element of @primary contains following array: # (link url, icon path, alt text, link text, condition, position) my $public; @@ -271,6 +272,9 @@ sub primary_menu { || (($env{'user.name'} eq '') && ($env{'user.domain'} eq ''))) { $public = 1; } + if (($menucoll) && (ref($menuref) eq 'HASH')) { + %menuopts = %{$menuref}; + } foreach my $menuitem (@primary_menu) { # evaluate conditions next if ref($menuitem) ne 'ARRAY'; # @@ -294,6 +298,28 @@ sub primary_menu { if ($position eq '') { $position = 'right'; } + if ($env{'request.course.id'} && $menucoll) { + if (($menuitem->[6]) && (!$menuopts{$menuitem->[6]})) { + if ($menuitem->[6] eq 'pers') { + if ($menuopts{'name'} && + $env{'user.name'} && $env{'user.domain'}) { + $menu{$position} .= '
  • '. + &Apache::loncommon::plainname($env{'user.name'}, + $env{'user.domain'}).'
  • '; + next; + } else { + next; + } + } else { + next; + } + } + } + my ($listclass,$linkattr); + if ($links_disabled) { + $listclass = 'LCisDisabled'; + $linkattr = 'aria-disabled="true"'; + } if (defined($primary_submenu{$title})) { my ($link,$target); if ($menuitem->[0] ne '') { @@ -310,17 +336,30 @@ sub primary_menu { ($item->[2] eq 'blog')) && (!&Apache::lonnet::usertools_access('','',$item->[2], undef,'tools'))); + if ($env{'request.course.id'} && $menucoll) { + next if ($item->[3]) && (!$menuopts{$item->[3]}); + } push(@primsub,$item); } - if (@primsub > 0) { - if ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'} ) { - $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); - } else { + if ($title eq 'Personal') { + if ($env{'user.name'} && $env{'user.domain'}) { + unless (($env{'request.course.id'}) && ($menucoll) && (!$menuopts{'name'})) { + $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}); + } + } + next if (($env{'request.course.id'}) && ($menucoll) && ($title eq 'Personal') && + (!@primsub)); + if ($title eq 'Personal') { $title = &mt($title); } - $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1); + } else { + $title = &mt($title); + } + if (@primsub > 0) { + $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1,undef,$listclass,$linkattr); } elsif ($link) { - $menu{$position} .= '
  • '.&mt($title).'
  • '; + $menu{$position} .= ($listclass?'
  • ':'
  • '). + ''.$title.'
  • '; } } } elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink @@ -331,13 +370,22 @@ sub primary_menu { 'helpdeskmail', $defdom,$origmail); if ($to ne '') { - $menu{$position} .= &prep_menuitem($menuitem); + $menu{$position} .= &prep_menuitem($menuitem,$listclass,$linkattr); } } else { - $menu{$position} .= '
  • '.&Apache::loncommon::top_nav_help('Help').'
  • '; + $menu{$position} .= ($listclass?'
  • ':'
  • '). + &Apache::loncommon::top_nav_help('Help',$linkattr). + '
  • '; } + } elsif ($$menuitem[3] eq 'Log In') { + if ($public) { + if (&Apache::lonnet::get_saml_landing()) { + $$menuitem[0] = '/adm/login'; + } + } + $menu{$position} .= prep_menuitem($menuitem,$listclass,$linkattr); } else { - $menu{$position} .= prep_menuitem($menuitem); + $menu{$position} .= prep_menuitem($menuitem,$listclass,$linkattr); } } my @output = ('',''); @@ -376,7 +424,7 @@ sub getauthor{ } sub secondary_menu { - my ($httphost) = @_; + my ($httphost,$ltiscope,$ltimenu,$noprimary,$menucoll,$menuref,$links_disabled) = @_; my $menu; my $crstype = &Apache::loncommon::course_type(); @@ -397,9 +445,10 @@ sub secondary_menu { my $canmodpara = &Apache::lonnet::allowed('opa', $crs_sec); my $canvgr = &Apache::lonnet::allowed('vgr', $crs_sec); my $canmgr = &Apache::lonnet::allowed('mgr', $crs_sec); + my $canplc = &Apache::lonnet::allowed('plc', $crs_sec); my $author = &getauthor(); - my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools); + my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools,%menuopts); $grouptools = 0; if ($env{'request.course.id'}) { $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; @@ -434,6 +483,15 @@ sub secondary_menu { } } } + if (($menucoll) && (ref($menuref) eq 'HASH')) { + %menuopts = %{$menuref}; + } + + my ($listclass,$linkattr); + if ($links_disabled) { + $listclass = 'LCisDisabled'; + $linkattr = 'aria-disabled="true"'; + } my ($canmodifycoauthor); if ($env{'request.role'} eq "au./$env{'user.domain'}/") { @@ -480,12 +538,21 @@ sub secondary_menu { && !$showsyllabus; next if $$menuitem[4] eq 'showfeeds' && !$showfeeds; + next if $$menuitem[4] eq 'plc' + && !$canplc; next if $$menuitem[4] eq 'author' && !$author; next if $$menuitem[4] eq 'cca' && !$canmodifycoauthor; my $title = $menuitem->[3]; + if ($env{'request.course.id'} && $menucoll) { + if ($$menuitem[5] eq 'main') { + next if ($menuopts{$$menuitem[5]} eq 'n'); + } elsif ($$menuitem[5] ne 'roles') { + next if (($$menuitem[5]) && (!$menuopts{$$menuitem[5]})); + } + } if (defined($secondary_submenu{$title})) { my ($link,$target); if ($menuitem->[0] ne '') { @@ -512,19 +579,26 @@ sub secondary_menu { } } if (@scndsub > 0) { - $menu .= &create_submenu($link,$target,$title,\@scndsub,1); + $menu .= &create_submenu($link,$target,&mt($title),\@scndsub,1,undef, + $listclass,$linkattr); } elsif ($link ne '#') { - $menu .= '
  • '.&mt($title).'
  • '; + $menu .= ($listclass?'
  • ':'
  • '). + ''. + &mt($title).'
  • '; } } } elsif ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) { # special treatment for role selector - ($roleswitcher_js,$roleswitcher_form,my $switcher) = + my ($switcher,$has_opa_priv); + ($roleswitcher_js,$roleswitcher_form,$switcher,$has_opa_priv) = &roles_selector( $env{'course.' . $env{'request.course.id'} . '.domain'}, $env{'course.' . $env{'request.course.id'} . '.num'}, $httphost ); + if (($$menuitem[5]) && (!$menuopts{$$menuitem[5]})) { + next unless ($has_opa_priv); + } $menu .= $switcher; } else { if ($$menuitem[3] eq 'Syllabus' && $env{'request.course.id'}) { @@ -539,7 +613,7 @@ sub secondary_menu { } if ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://}) { if (($ENV{'SERVER_PORT'} == 443) || ($env{'request.use_absolute'} =~ m{^https://})) { - unless (&Apache::lonnet::uses_sts()) { + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl())) { unless ($$menuitem[0] =~ m{^https?://}) { $$menuitem[0] = 'http://'.$ENV{'SERVER_NAME'}.$$menuitem[0]; } @@ -551,7 +625,7 @@ sub secondary_menu { } $$menuitem[0] = &HTML::Entities::encode($$menuitem[0],'&<>"'); } - $menu .= &prep_menuitem(\@$menuitem); + $menu .= &prep_menuitem(\@$menuitem,$listclass,$linkattr); } } if ($menu =~ /\[url\].*\[symb\]/) { @@ -574,6 +648,7 @@ sub secondary_menu { } $menu =~ s/\[uname\]/$$author{user}/g; $menu =~ s/\[udom\]/$$author{dom}/g; + $menu =~ s/\[javascript\]/javascript:/g; if ($env{'request.course.id'}) { $menu =~ s/\[cnum\]/$cnum/g; $menu =~ s/\[cdom\]/$cdom/g; @@ -588,7 +663,7 @@ sub secondary_menu { } sub create_submenu { - my ($link,$target,$title,$submenu,$translate,$addclass) = @_; + my ($link,$target,$title,$submenu,$translate,$addclass,$listclass,$linkattr) = @_; return unless (ref($submenu) eq 'ARRAY'); my $disptarget; if ($target ne '') { @@ -603,7 +678,7 @@ sub create_submenu { # $link and $title are only used in the initial string written in $menu # as seen above, not needed for nested submenus - $menu .= &build_submenu($target, $submenu, $translate, '1'); + $menu .= &build_submenu($target, $submenu, $translate, '1', $listclass, $linkattr); $menu .= ''; return $menu; @@ -613,7 +688,7 @@ sub create_submenu { # build the dropdown (and nested submenus) recursively # see perldoc create_submenu documentation for further information sub build_submenu { - my ($target, $submenu, $translate, $first_level) = @_; + my ($target, $submenu, $translate, $first_level, $listclass, $linkattr) = @_; unless (@{$submenu}) { return ''; } @@ -676,8 +751,10 @@ sub build_submenu { $target = ' target="_top"'; } - $menu .= '
  • '; - $menu .= '' . $title . ''; + $menu .= '
  • '; + $menu .= '' . $title . ''; $menu .= '
  • '; } } @@ -1018,15 +1095,17 @@ if ($env{'browser.mobile'}) { $is_mobile = 1; } - unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio|ext\.tool)(\?|$)/) { + unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio)(\?|$)/) { if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/}) && - ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/(docs/|default_\d+\.page$)})) { + ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/(docs/|default_\d+\.page$)}) && + ($env{'request.noversionuri'} !~ m{^/adm/.+/ext\.tool$})) { $menuitems.=(< 'Key:', nokey => 'A proctor key is required', ); + my $shownsymb = &HTML::Entities::encode(&Apache::lonenc::check_encrypt($env{'request.symb'})); my $navmap = Apache::lonnavmaps::navmap->new(); my ($missing,$tried) = (0,0); if (ref($navmap)) { @@ -2282,6 +2367,7 @@ sub done_button_js {
    +
    @@ -2363,6 +2449,7 @@ END
    +
    @@ -2551,11 +2638,11 @@ function golist(url) { -function catalog_info(isMobile) { +function catalog_info(url,isMobile) { if (isMobile == 1) { - openMyModal(window.location.pathname+'.meta?modal=1',500,400,'yes'); + openMyModal(url+'.meta?modal=1',500,400,'yes'); } else { - loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=500,width=400,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no'); + loncatinfo=window.open(url+'.meta',"LONcatInfo",'height=500,width=400,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no'); } } @@ -2677,7 +2764,7 @@ sub roles_selector { my $now = time; my (%courseroles,%seccount,%courseprivs,%roledesc); my $is_cc; - my ($js,$form,$switcher); + my ($js,$form,$switcher,$has_opa_priv); my $ccrole; if ($crstype eq 'Community') { $ccrole = 'co'; @@ -2798,12 +2885,19 @@ sub roles_selector { if ($env{'request.role'} =~ m{^\Q$role\E}) { if ($seccount{$role} > 1) { $include = 1; + } else { + if ($env{'user.priv.'.$env{'request.role'}."./$cdom/$cnum"} =~/opa\&([^\:]*)/) { + $has_opa_priv = 1; + } } } else { $include = 1; } } if ($include) { + if ($env{"user.priv.$role./$cdom/$cnum./$cdom/$cnum"} =~/opa\&([^\:]*)/) { + $has_opa_priv = 1; + } push(@submenu,['javascript:adhocRole('."'$role'".')', &Apache::lonnet::plaintext($role,$crstype)]); } @@ -2828,6 +2922,9 @@ sub roles_selector { } else { $rolename = &Apache::lonnet::plaintext($role); } + if ($env{"user.priv.$role./$cdom/$cnum./$cdom/$cnum"} =~/opa\&([^\:]*)/) { + $has_opa_priv = 1; + } push(@submenu,['javascript:adhocRole('."'$role'".')', $rolename]); } @@ -2837,7 +2934,7 @@ sub roles_selector { $switcher = &create_submenu('','',&mt('Switch role'),\@submenu); } } - return ($js,$form,$switcher); + return ($js,$form,$switcher,$has_opa_priv); } sub get_all_courseroles { @@ -3268,13 +3365,13 @@ BEGIN { $category_positions{$entries[2]}=$entries[1]; $category_names{$entries[2]}=$entries[3]; } elsif ($configline=~/^prim\:/) { - my @entries = (split(/\:/, $configline))[1..6]; + my @entries = (split(/\:/, $configline))[1..7]; push(@primary_menu,\@entries); } elsif ($configline=~/^primsub\:/) { - my ($parent,@entries) = (split(/\:/, $configline))[1..4]; + my ($parent,@entries) = (split(/\:/, $configline))[1..5]; push(@{$primary_submenu{$parent}},\@entries); } elsif ($configline=~/^scnd\:/) { - my @entries = (split(/\:/, $configline))[1..5]; + my @entries = (split(/\:/, $configline))[1..6]; push(@secondary_menu,\@entries); } elsif ($configline=~/^scndsub\:/) { my ($parent,@entries) = (split(/\:/, $configline))[1..4];