[LON-CAPA-cvs] cvs: loncom /interface loncommon.pm lonmenu.pm mydesk.tab

raeburn raeburn at source.lon-capa.org
Sun Jun 6 23:32:02 EDT 2021


raeburn		Mon Jun  7 03:32:02 2021 EDT

  Modified files:              
    /loncom/interface	loncommon.pm lonmenu.pm mydesk.tab 
  Log:
  - Bug 6907
    - Display of menu items in course context determined by menu collection
      in effect (if set).
  
  
-------------- next part --------------
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1358 loncom/interface/loncommon.pm:1.1359
--- loncom/interface/loncommon.pm:1.1358	Fri May  7 20:07:02 2021
+++ loncom/interface/loncommon.pm	Mon Jun  7 03:32:02 2021
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1358 2021/05/07 20:07:02 raeburn Exp $
+# $Id: loncommon.pm,v 1.1359 2021/06/07 03:32:02 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -6115,7 +6115,8 @@
 
 sub bodytag {
     my ($title,$function,$addentries,$bodyonly,$domain,$forcereg,
-        $no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,$ltimenu)=@_;
+        $no_nav_bar,$bgcolor,$args,$advtoolsref,$ltiscope,$ltiuri,
+        $ltimenu,$menucoll,$menuref)=@_;
 
     my $public;
     if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
@@ -6199,6 +6200,7 @@
 	undef($role);
     }
 
+    my $showcrstitle = 1;
     if (($cid) && ($env{'request.lti.login'})) {
         if (ref($ltimenu) eq 'HASH') {
             unless ($ltimenu->{'role'}) {
@@ -6206,6 +6208,17 @@
             }
             unless ($ltimenu->{'coursetitle'}) {
                 $realm=' ';
+                $showcrstitle = 0;
+            }
+        }
+    } elsif (($cid) && ($menucoll)) {
+        if (ref($menuref) eq 'HASH') {
+            unless ($menuref->{'role'}) {
+                undef($role);
+            }
+            unless ($menuref->{'crs'}) {
+                $realm=' ';
+                $showcrstitle = 0;
             }
         }
     }
@@ -6214,7 +6227,7 @@
     #
     # Extra info if you are the DC
     my $dc_info = '';
-    if (($env{'user.adv'}) && ($env{'request.course.id'}) &&
+    if (($env{'user.adv'}) && ($env{'request.course.id'}) && $showcrstitle &&
         (exists($env{'user.role.dc./'.$env{'course.'.$cid.'.domain'}.'/'}))) {
         $dc_info = $cid.' '.$env{'course.'.$cid.'.internal.coursecode'};
         $dc_info =~ s/\s+$//;
@@ -6242,7 +6255,7 @@
             Apache::lonmenu::utilityfunctions($httphost), 'start');
 
         unless ($args->{'no_primary_menu'}) {
-            my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu);
+            my ($left,$right) = Apache::lonmenu::primary_menu($crstype,$ltimenu,$menucoll,$menuref);
 
             if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) {
                 if ($dc_info) {
@@ -6273,7 +6286,8 @@
         if (!$public){
             unless ($args->{'no_inline_menu'}) {
                 $bodytag .= Apache::lonmenu::secondary_menu($httphost,$ltiscope,$ltimenu,
-                                                            $args->{'no_primary_menu'});
+                                                            $args->{'no_primary_menu'},
+                                                            $menucoll,$menuref);
             }
             $bodytag .= Apache::lonmenu::serverform();
             $bodytag .= Apache::lonhtmlcommon::scripttag('', 'end');
@@ -8950,7 +8964,7 @@
     #&Apache::lonnet::logthis("start_page ".join(':',caller(0)));
 
     $env{'internal.start_page'}++;
-    my ($result, at advtools,$ltiscope,$ltiuri,%ltimenu);
+    my ($result, at advtools,$ltiscope,$ltiuri,%ltimenu,$menucoll,%menu);
 
     if (! exists($args->{'skip_phases'}{'head'}) ) {
         $result .= &xml_begin($args->{'frameset'}) . &headtag($title, $head_extra, $args);
@@ -8985,8 +8999,47 @@
         ($ltiscope,$ltiuri) = &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'},
                                   $env{'course.'.$env{'request.course.id'}.'.domain'},
                                   $env{'course.'.$env{'request.course.id'}.'.num'});
+    } elsif ($env{'request.course.id'}) {
+        my $expiretime=600;
+        if ((time-$env{'course.'.$env{'request.course.id'}.'.last_cache'}) > $expiretime) {
+            &Apache::lonnet::coursedescription($env{'request.course.id'},{'freshen_cache' => 1});
+        }
+        my ($deeplinkmenu,$menuref);
+        ($menucoll,$deeplinkmenu,$menuref) = &menucoll_in_effect();
+        if ($menucoll) {
+            if (ref($menuref) eq 'HASH') {
+                %menu = %{$menuref};
+            }
+            if ($menu{'top'} eq 'n') {
+                $args->{'no_primary_menu'} = 1;
+            }
+            if ($menu{'inline'} eq 'n') {
+                unless (&Apache::lonnet::allowed('opa')) {
+                    my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+                    my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+                    my $crstype = &course_type();
+                    my $now = time;
+                    my $ccrole;
+                    if ($crstype eq 'Community') {
+                        $ccrole = 'co';
+                    } else {
+                        $ccrole = 'cc';
+                    }
+                    if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) {
+                        my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum});
+                        if ((($start) && ($start<0)) ||
+                            (($end) && ($end<$now))  ||
+                            (($start) && ($now<$start))) {
+                            $args->{'no_inline_menu'} = 1;
+                        }
+                    } else {
+                        $args->{'no_inline_menu'} = 1;
+                    }
+                }
+            }
+        }
     }
-    
+
     if (! exists($args->{'skip_phases'}{'body'}) ) {
 	if ($args->{'frameset'}) {
 	    my $attr_string = &make_attr_string($args->{'force_register'},
@@ -8999,7 +9052,7 @@
                          $args->{'only_body'},      $args->{'domain'},
                          $args->{'force_register'}, $args->{'no_nav_bar'},
                          $args->{'bgcolor'},        $args,
-                         \@advtools,$ltiscope,$ltiuri,\%ltimenu);
+                         \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll,\%menu);
         }
     }
 
@@ -9085,6 +9138,28 @@
     return $result;
 }
 
+sub menucoll_in_effect {
+    my ($menucoll,$deeplinkmenu,%menu);
+    if ($env{'request.course.id'}) {
+        $menucoll = $env{'course.'.$env{'request.course.id'}.'.menudefault'};
+        if (($env{'request.deeplink.login'}) &&
+            ($env{'request.noversionuri'} =~ m{^/(res|uploaded)/})) {
+            my $deeplink = &EXT('resource.0.deeplink');
+            if ($deeplink ne '') {
+                my ($listed,$scope,$access,$display) = split(/,/,$deeplink);
+                if ($display =~ /^\d+$/) {
+                    $deeplinkmenu = 1;
+                    $menucoll = $display;
+                }
+            }
+        }
+        if ($menucoll) {
+            %menu = &page_menu($env{'course.'.$env{'request.course.id'}.'.menucollections'},$menucoll);
+        }
+    }
+    return ($menucoll,$deeplinkmenu,\%menu);
+}
+
 sub wishlist_window {
     return(<<'ENDWISHLIST');
 <script type="text/javascript">
@@ -18651,6 +18726,37 @@
     return $uselink;
 }
 
+sub page_menu {
+    my ($menucolls,$menunum) = @_;
+    my %menu;
+    foreach my $item (split(/;/,$menucolls)) {
+        my ($num,$value) = split(/\%/,$item);
+        if ($num eq $menunum) {
+            my @entries = split(/\&/,$value);
+            foreach my $entry (@entries) {
+                my ($name,$fields) = split(/=/,$entry);
+                if (($name eq 'top') || ($name eq 'inline') || ($name eq 'main')) {
+                    $menu{$name} = $fields;
+                } else {
+                    my @shown;
+                    if ($fields =~ /,/) {
+                        @shown = split(/,/,$fields);
+                    } else {
+                        @shown = ($fields);
+                    }
+                    if (@shown) {
+                        foreach my $field (@shown) {
+                            next if ($field eq '');
+                            $menu{$field} = 1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return %menu;
+}
+
 1;
 __END__;
 
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.506 loncom/interface/lonmenu.pm:1.507
--- loncom/interface/lonmenu.pm:1.506	Thu Apr 29 17:45:22 2021
+++ loncom/interface/lonmenu.pm	Mon Jun  7 03:32:02 2021
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.506 2021/04/29 17:45:22 raeburn Exp $
+# $Id: lonmenu.pm,v 1.507 2021/06/07 03:32:02 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -247,8 +247,8 @@
 # @primary_menu is filled within the BEGIN block of this module with 
 # entries from mydesk.tab
 sub primary_menu {
-    my ($crstype,$ltimenu) = @_;
-    my (%menu,%ltiexc);
+    my ($crstype,$ltimenu,$menucoll,$menuref) = @_;
+    my (%menu,%ltiexc,%menuopts);
     # each element of @primary contains following array:
     # (link url, icon path, alt text, link text, condition, position)
     my $public;
@@ -277,6 +277,9 @@
             }
         }
     }
+    if (($menucoll) && (ref($menuref) eq 'HASH')) {
+        %menuopts = %{$menuref};
+    }
     foreach my $menuitem (@primary_menu) {
         # evaluate conditions 
         next if    ref($menuitem)       ne 'ARRAY';    #
@@ -312,6 +315,9 @@
         if ($position eq '') {
             $position = 'right';
         }
+        if ($env{'request.course.id'} && $menucoll) {
+             next if (($menuitem->[6]) && (!$menuopts{$menuitem->[6]}));
+        }
         if (defined($primary_submenu{$title})) {
             my ($link,$target);
             if ($menuitem->[0] ne '') {
@@ -331,10 +337,14 @@
                              ($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 ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'} ) {
-                    unless ($ltiexc{'fullname'}) {
+                    unless (($ltiexc{'fullname'}) || 
+                            (($env{'request.course.id'}) && ($menucoll) && (!$menuopts{'name'}))) {
                         $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                     }
                 } else {
@@ -400,7 +410,7 @@
 }
 
 sub secondary_menu {
-    my ($httphost,$ltiscope,$ltimenu,$noprimary) = @_;
+    my ($httphost,$ltiscope,$ltimenu,$noprimary,$menucoll,$menuref) = @_;
     my $menu;
 
     my $crstype = &Apache::loncommon::course_type();
@@ -424,7 +434,8 @@
     my $canplc        = &Apache::lonnet::allowed('plc', $crs_sec);
     my $author        = &getauthor();
 
-    my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools,$lti,$ltimapres,%ltiexc);
+    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'};
@@ -472,6 +483,9 @@
             }
         }
     }
+    if (($menucoll) && (ref($menuref) eq 'HASH')) {
+        %menuopts = %{$menuref};
+    }
 
     my ($canmodifycoauthor); 
     if ($env{'request.role'} eq "au./$env{'user.domain'}/") {
@@ -534,11 +548,16 @@
                 && $ltiexc{'logout'};
 
         my $title = $menuitem->[3];
+        if ($env{'request.course.id'} && $menucoll) {
+            unless ($$menuitem[5] eq 'roles') {
+                next if (($$menuitem[5]) && (!$menuopts{$$menuitem[5]}));
+            }
+        }
         if (defined($secondary_submenu{$title})) {
             my ($link,$target);
             if ($menuitem->[0] ne '') {
                 $link = $menuitem->[0];
-                unless ($ltitarget eq 'iframe') {   
+                unless ($ltitarget eq 'iframe') {
                     $target = '_top';
                 }
             } else {
@@ -568,7 +587,7 @@
                         push(@scndsub,$item);
                     }
                 }
-                if ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'} ) {
+                if ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'}) {
                     unless ($ltiexc{'fullname'}) {
                         $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                     }
@@ -581,12 +600,16 @@
             }
         } 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,$ltitarget
                 );
+            if (($$menuitem[5]) && (!$menuopts{$$menuitem[5]})) {
+                next unless ($has_opa_priv);
+            }
             $menu .= $switcher;
         } elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink
             next if ($crstype eq 'Placement');
@@ -2394,7 +2417,7 @@
     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';
@@ -2515,12 +2538,19 @@
                 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)]);
             }
@@ -2545,6 +2575,9 @@
                     } 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]);
                 }
@@ -2554,7 +2587,7 @@
             $switcher = &create_submenu('','',&mt('Switch role'),\@submenu,'','',$ltitarget);
         }
     }
-    return ($js,$form,$switcher);
+    return ($js,$form,$switcher,$has_opa_priv);
 }
 
 sub get_all_courseroles {
@@ -3002,13 +3035,13 @@
                         $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, at entries) = (split(/\:/, $configline))[1..4];
+                        my ($parent, at 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, at entries) = (split(/\:/, $configline))[1..4];
Index: loncom/interface/mydesk.tab
diff -u loncom/interface/mydesk.tab:1.181 loncom/interface/mydesk.tab:1.182
--- loncom/interface/mydesk.tab:1.181	Tue May  8 20:30:12 2018
+++ loncom/interface/mydesk.tab	Mon Jun  7 03:32:02 2021
@@ -1,4 +1,4 @@
-# $Id: mydesk.tab,v 1.181 2018/05/08 20:30:12 raeburn Exp $
+# $Id: mydesk.tab,v 1.182 2021/06/07 03:32:02 raeburn Exp $
 # primary menu links
 # Apache::lonmenu::primary_menu() generates a menu from these elements
 # prim: item belongs to primary menu
@@ -21,18 +21,19 @@
 #   possible positions: 
 #   - empty (will be displayed on right side -- default location).
 #   - left
-# prim:link:icon:alt:text:condition:position
-prim::::Personal::left
-prim:/adm/about.html:/adm/lonIcons/minilogo.gif:LON-CAPA Logo:About:public:
-prim:/adm/menu:::Home:notlti:
-prim:/adm/communicate:::Messages:nonewmsg:
-prim:/adm/communicate:::New Messages:newmsg:
-prim:/adm/roles:::Roles:roles:
-prim:/adm/roles:::Courses:courses:
+# name: short name for item (used in visibility check for menu collection in effect)
+# prim:link:icon:alt:text:condition:position:name
+prim::::Personal::left:pers
+prim:/adm/about.html:/adm/lonIcons/minilogo.gif:LON-CAPA Logo:About:public::logo
+prim:/adm/menu:::Home:notlti::menu
+prim:/adm/communicate:::Messages:nonewmsg::comm
+prim:/adm/communicate:::New Messages:newmsg::comm
+prim:/adm/roles:::Roles:roles::roles
+prim:/adm/roles:::Courses:courses::roles
 prim:/adm/helpdesk:::Help:onlypublic:
 prim:/adm/roles:::Log In:onlypublic:
-prim::::Help::
-prim:/adm/logout:::Logout:ltiexc:
+prim::::Help:::help
+prim:/adm/logout:::Logout:ltiexc::logout
 
 # primary sub-menu links
 # Apache::lonmenu::primary_menu() generates a sub-menus from these elements
@@ -47,13 +48,14 @@
 #   - blog: link displayed if blog access
 #   - wishlist: link displayed if user has privileges to use Stored Links
 #   - reqcrs: link displayed if user can request Course or Community creation
-# primsub:parent:link:text:condition
-primsub:Personal:/adm/[domain]/[user]/aboutme:Information:
-primsub:Personal:/adm/preferences:Preferences:
-primsub:Personal:/adm/portfolio:Portfolio:portfolio
-primsub:Personal:/adm/wishlist:Stored Links:wishlist
-primsub:Personal:/adm/announcements:Calendar:
-primsub:Personal:/adm/[domain]/[user]/_rss.html:Feeds:blog
+# name: short name for item (used in visibility check for menu collection in effect)
+# primsub:parent:link:text:condition:name
+primsub:Personal:/adm/[domain]/[user]/aboutme:Information::about
+primsub:Personal:/adm/preferences:Preferences::prefs
+primsub:Personal:/adm/portfolio:Portfolio:portfolio:port
+primsub:Personal:/adm/wishlist:Stored Links:wishlist:wish
+primsub:Personal:/adm/announcements:Calendar::anno
+primsub:Personal:/adm/[domain]/[user]/_rss.html:Feeds:blog:rss
 
 # secondary menu links
 # Apache::lonmenu::secondary_menu() generates a menu from these elements
@@ -83,22 +85,23 @@
 #   - lti: LTI launch -- LTI-specific rules apply
 #   - notlti: not LTI launch
 #   - notltimapres: not LTI launch for specific map or resource
-# scnd:link:icon:alt:text:condition
+# name: short name for item (used in visibility check for menu collection in effect)
+# scnd:link:icon:alt:text:condition:name
 scnd::::Personal:lti
-scnd:/adm/navmaps?postdata=[url]&postsymb=[symb]:::Contents:notltimapres
+scnd:/adm/navmaps?postdata=[url]&postsymb=[symb]:::Contents:notltimapres:cont
 scnd:/adm/whatsnew:::What's New:whn
-scnd:/adm/quickgrades:::Grades:nvgr
-scnd:[javascript]chat_win();:::Chat:plc
+scnd:/adm/quickgrades:::Grades:nvgr:grades
+scnd:[javascript]chat_win();:::Chat:plc:chat
 scnd::::Grades:vgr
 scnd::::People:viewusers
 scnd::::Settings:params
-scnd:/adm/viewclasslist:::People:noviewusers
-scnd:/adm/coursegroups:::Groups:showgroups
-scnd:/adm/slotrequest?command=manageresv:::Reservations:showresv
+scnd:/adm/viewclasslist:::People:noviewusers:people
+scnd:/adm/coursegroups:::Groups:showgroups:groups
+scnd:/adm/slotrequest?command=manageresv:::Reservations:showresv:resv
 scnd::::Public:crsedit
-scnd:/public/[cdom]/[cnum]/syllabus:::Syllabus:showsyllabus
-scnd:/adm/[cdom]/[cnum]/_rss.html:::Feeds:showfeeds
-scnd:/adm/roles:::Roles:notlti
+scnd:/public/[cdom]/[cnum]/syllabus:::Syllabus:showsyllabus:syll
+scnd:/adm/[cdom]/[cnum]/_rss.html:::Feeds:showfeeds:feeds
+scnd:/adm/roles:::Roles:notlti:roles
 scnd:/adm/communicate:::Messages:lti
 scnd::::Help:lti
 scnd:/adm/logout:::Logout:lti


More information about the LON-CAPA-cvs mailing list