--- loncom/interface/lonmenu.pm 2016/08/13 21:14:50 1.369.2.57
+++ loncom/interface/lonmenu.pm 2017/01/30 19:06:46 1.369.2.69
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines to control the menu
#
-# $Id: lonmenu.pm,v 1.369.2.57 2016/08/13 21:14:50 raeburn Exp $
+# $Id: lonmenu.pm,v 1.369.2.69 2017/01/30 19:06:46 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -132,6 +132,33 @@ Inputs: 6 - (a) link and (b) target for
(f) optional class for
element in primary menu, for which
sub menu is being generated.
+The underlying datastructure used in (d) contains data from mydesk.tab.
+It consists of an array which has an array for each item appearing in
+the menu (e.g. [["link", "title", "condition"]] for a single-item menu).
+create_submenu() supports also the creation of XHTML for nested dropdown
+menus represented by unordered lists. This is done by replacing the
+scalar used for the link with an arrayreference containing the menuitems
+for the nested menu. This can be done recursively so that the next menu
+may also contain nested submenus.
+
+ Example:
+ [ # begin of datastructure
+ ["/home/", "Home", "condition1"], # 1st item of the 1st layer menu
+ [ # 2nd item of the 1st layer menu
+ [ # anon. array for nested menu
+ ["/path1", "Path1", undef], # 1st item of the 2nd layer menu
+ ["/path2", "Path2", undef], # 2nd item of the 2nd layer menu
+ [ # 3rd item of the 2nd layer menu
+ [[...], [...], ..., [...]], # containing another menu layer
+ "Sub-Sub-Menu", # title for this container
+ undef
+ ]
+ ], # end of array/nested menu
+ "Sub-Menu", # title for the container item
+ undef
+ ] # end of 2nd item of the 1st layer menu
+]
+
=item innerregister()
@@ -286,6 +313,11 @@ sub primary_menu {
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 {
+ $title = &mt($title);
+ }
$menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1);
} elsif ($link) {
$menu{$position} .= ''.&mt($title).'';
@@ -352,13 +384,16 @@ sub secondary_menu {
? "/$env{'request.course.sec'}"
: '');
my $canedit = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
+ my $canvieweditor = &Apache::lonnet::allowed('cev', $env{'request.course.id'});
my $canviewroster = $env{'course.'.$env{'request.course.id'}.'.student_classlist_view'};
if ($canviewroster eq 'disabled') {
undef($canviewroster);
}
my $canviewgrps = &Apache::lonnet::allowed('vcg', $crs_sec);
my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);
+ my $canviewusers = &Apache::lonnet::allowed('vcl', $crs_sec);
my $canviewwnew = &Apache::lonnet::allowed('whn', $crs_sec);
+ my $canviewpara = &Apache::lonnet::allowed('vpa', $crs_sec);
my $canmodpara = &Apache::lonnet::allowed('opa', $crs_sec);
my $canvgr = &Apache::lonnet::allowed('vgr', $crs_sec);
my $canmgr = &Apache::lonnet::allowed('mgr', $crs_sec);
@@ -368,7 +403,7 @@ sub secondary_menu {
if ($env{'request.course.id'}) {
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- unless ($canedit) {
+ unless ($canedit || $canvieweditor) {
unless (&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) {
if (($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) ||
($env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) ||
@@ -381,7 +416,7 @@ sub secondary_menu {
$showfeeds = 1;
}
}
- unless ($canmgr) {
+ unless ($canmgr || $canvgr) {
my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
if (keys(%slots) > 0) {
$showresv = 1;
@@ -411,28 +446,28 @@ sub secondary_menu {
next if $$menuitem[4] ne 'always'
&& ($$menuitem[4] ne 'author' && $$menuitem[4] ne 'cca')
&& !$env{'request.course.id'};
- next if $$menuitem[4] =~ /^mdc/
- && !$canedit;
- next if $$menuitem[4] eq 'mdcCourse'
+ next if $$menuitem[4] =~ /^crsedit/
+ && (!$canedit && !$canvieweditor);
+ next if $$menuitem[4] eq 'crseditCourse'
&& ($crstype eq 'Community');
- next if $$menuitem[4] eq 'mdcCommunity'
+ next if $$menuitem[4] eq 'crseditCommunity'
&& ($crstype eq 'Course');
next if $$menuitem[4] eq 'nvgr'
&& $canvgr;
next if $$menuitem[4] eq 'vgr'
&& !$canvgr;
- next if $$menuitem[4] eq 'cst'
- && !$canmodifyuser;
- next if $$menuitem[4] eq 'ncst'
- && ($canmodifyuser || !$canviewroster);
+ next if $$menuitem[4] eq 'viewusers'
+ && !$canmodifyuser && !$canviewusers;
+ next if $$menuitem[4] eq 'noviewusers'
+ && ($canmodifyuser || $canviewusers || !$canviewroster);
next if $$menuitem[4] eq 'mgr'
&& !$canmgr;
next if $$menuitem[4] eq 'showresv'
&& !$showresv;
next if $$menuitem[4] eq 'whn'
&& !$canviewwnew;
- next if $$menuitem[4] eq 'opa'
- && !$canmodpara;
+ next if $$menuitem[4] eq 'params'
+ && (!$canmodpara && !$canviewpara);
next if $$menuitem[4] eq 'nvcg'
&& ($canviewgrps || !%groups);
next if $$menuitem[4] eq 'showsyllabus'
@@ -459,10 +494,11 @@ sub secondary_menu {
if (ref($item) eq 'ARRAY') {
next if ($item->[2] eq 'vgr' && !$canvgr);
next if ($item->[2] eq 'opa' && !$canmodpara);
- next if ($item->[2] eq 'cst' && !$canmodifyuser);
+ next if ($item->[2] eq 'vpa' && !$canviewpara);
+ next if ($item->[2] eq 'viewusers' && !($canmodifyuser || $canviewusers));
next if ($item->[2] eq 'mgr' && !$canmgr);
next if ($item->[2] eq 'vcg' && !$canviewgrps);
- next if ($item->[2] eq 'mdc' && !$canedit);
+ next if ($item->[2] eq 'crsedit' && !$canedit && !$canvieweditor);
push(@scndsub,$item);
}
}
@@ -536,51 +572,80 @@ sub create_submenu {
if ($target ne '') {
$disptarget = ' target="'.$target.'"';
}
- my $name;
- if ($title eq 'Personal') {
- if ($env{'user.name'} && $env{'user.domain'}) {
- $name = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
- } else {
- $name = &mt($title);
- }
- } else {
- $name = &mt($title);
- }
my $menu = ''.
''.
- ''.$name.
+ ''.$title.
''.
' ▼'.
'';
+
+ # $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 .= '
';
+
+ return $menu;
+}
+
+# helper routine for 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) = @_;
+ unless (@{$submenu}) {
+ return '';
+ }
+
+ my $menu = '';
my $count = 0;
my $numsub = scalar(@{$submenu});
foreach my $item (@{$submenu}) {
$count ++;
if (ref($item) eq 'ARRAY') {
my $href = $item->[0];
- if ($href =~ /(aboutme|rss\.html)$/) {
- next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
- $href =~ s/\[domain\]/$env{'user.domain'}/g;
- $href =~ s/\[user\]/$env{'user.name'}/g;
- }
+ my $bordertop;
my $borderbot;
- if ($count == $numsub) {
- $borderbot = 'border-bottom:1px solid black;';
- }
- unless (($href eq '') || ($href =~ /^\#/)) {
- $target = ' target="_top"';
- }
- $menu .= '';
+ my $title;
+
if ($translate) {
- $menu .= &mt($item->[1]);
+ $title = &mt($item->[1]);
} else {
- $menu .= $item->[1];
+ $title = $item->[1];
+ }
+
+ if ($count == 1 && !$first_level) {
+ $bordertop = 'border-top: 1px solid black;';
+ }
+ if ($count == $numsub) {
+ $borderbot = 'border-bottom: 1px solid black;';
+ }
+
+ # href is a reference to another submenu
+ if (ref($href) eq 'ARRAY') {
+ $menu .= '';
+ $menu .= '';
+ $menu .= '';
+ $menu .= &build_submenu($target, $href, $translate);
+ $menu .= '
';
+ $menu .= '';
+ } else { # href is the actual hyperlink and does not represent another submenu
+ # for the current menu title
+ if ($href =~ /(aboutme|rss\.html)$/) {
+ next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
+ $href =~ s/\[domain\]/$env{'user.domain'}/g;
+ $href =~ s/\[user\]/$env{'user.name'}/g;
+ }
+ unless (($href eq '') || ($href =~ /^\#/)) {
+ $target = ' target="_top"';
+ }
+
+ $menu .= '';
+ $menu .= '' . $title . '';
+ $menu .= '';
}
- $menu .= '';
}
}
- $menu .= '';
return $menu;
}
@@ -613,7 +678,7 @@ sub registerurl {
}
sub innerregister {
- my ($forcereg,$bread_crumbs,$group) = @_;
+ my ($forcereg,$bread_crumbs,$group,$pagebuttonshide) = @_;
my $const_space = ($env{'request.state'} eq 'construct');
my $is_const_dir = 0;
@@ -759,12 +824,13 @@ sub innerregister {
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
$perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
+ $perms{'cev'} = &Apache::lonnet::allowed('cev',$env{'request.course.id'});
my @privs;
if ($env{'request.symb'} ne '') {
if ($env{'request.filename'}=~/$LONCAPA::assess_re/) {
push(@privs,('mgr','vgr'));
}
- push(@privs,'opa');
+ push(@privs,('opa','vpa'));
}
foreach my $priv (@privs) {
$perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});
@@ -790,7 +856,7 @@ sub innerregister {
'Content Submissions');
}
}
- if (($env{'request.symb'} ne '') && ($perms{'opa'})) {
+ if (($env{'request.symb'} ne '') && (($perms{'opa'}) || ($perms{'vpa'}))) {
$hwkadd .= &switch('','',7,3,'pparm.png','Content Settings',
'parms[_2]',"gocmd('/adm/parmset','set')",
'Content Settings');
@@ -800,7 +866,7 @@ sub innerregister {
#
# This applies to items inside a folder/page modifiable in the course.
#
- if (($env{'request.symb'}=~/^uploaded/) && ($perms{'mdc'})) {
+ if (($env{'request.symb'}=~/^uploaded/) && (($perms{'mdc'}) || ($perms{'cev'}))) {
my $text = 'Edit Folder';
if (($mapurl =~ /\.page$/) ||
($env{'request.symb'}=~
@@ -967,22 +1033,24 @@ ENDMENUITEMS
my $addremote=0;
foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
if ($addremote) {
-
- &Apache::lonhtmlcommon::clear_breadcrumb_tools();
-
- &Apache::lonhtmlcommon::add_breadcrumb_tool(
- 'navigation', @inlineremote[21,23]);
-
- my $countdown;
+ my ($countdown,$buttonshide);
if ($env{'request.filename'} =~ /\.page$/) {
my %breadcrumb_tools = &Apache::lonhtmlcommon::current_breadcrumb_tools();
if (ref($breadcrumb_tools{'tools'}) eq 'ARRAY') {
- $countdown = $breadcrumb_tools{'tools'}[0];
+ $countdown = $breadcrumb_tools{'tools'}->[0];
}
+ $buttonshide = $pagebuttonshide;
} else {
$countdown = &countdown_timer();
+ $buttonshide = &hidden_button_check();
}
- if (&hidden_button_check() eq 'yes') {
+
+ &Apache::lonhtmlcommon::clear_breadcrumb_tools();
+
+ &Apache::lonhtmlcommon::add_breadcrumb_tool(
+ 'navigation', @inlineremote[21,23]);
+
+ if ($buttonshide eq 'yes') {
if ($countdown) {
&Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);
}
@@ -1335,9 +1403,9 @@ sub get_editbutton {
my ($cfile,$home,$switchserver,$forceedit,$forceview,$forcereg) = @_;
my $jscall;
if (($forceview) && ($env{'form.todocs'})) {
- my ($folderpath,$command);
+ my ($folderpath,$command,$navmap);
if ($env{'request.symb'}) {
- $folderpath = &Apache::loncommon::symb_to_docspath($env{'request.symb'});
+ $folderpath = &Apache::loncommon::symb_to_docspath($env{'request.symb'},\$navmap);
} elsif ($env{'form.folderpath'} =~ /^supplemental/) {
$folderpath = $env{'form.folderpath'};
$command = '&forcesupplement=1';
@@ -1345,11 +1413,16 @@ sub get_editbutton {
$folderpath = &escape(&HTML::Entities::encode(&escape($folderpath),'<>&"'));
$jscall = "go('/adm/coursedocs?folderpath=$folderpath$command')";
} else {
+ my $suppanchor;
+ if ($env{'form.folderpath'}) {
+ $suppanchor = $env{'form.anchor'};
+ }
$jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,$switchserver,
$forceedit,$forcereg,$env{'request.symb'},
&escape($env{'form.folderpath'}),
&escape($env{'form.title'}),$env{'form.idx'},
- &escape($env{'form.suppurl'},$env{'form.todocs'}));
+ &escape($env{'form.suppurl'}),$env{'form.todocs'},
+ $suppanchor);
}
if ($jscall) {
my $icon = 'pcstr.png';
@@ -1521,9 +1594,13 @@ sub prepare_functions {
($resurl =~ m{^/adm/$match_domain/$match_username/aboutme$}))) {
my @folders=split('&',$env{'form.folderpath'});
if ((@folders > 2) || ($resurl ne '/adm/supplemental')) {
+ my $suppanchor;
+ if ($resurl =~ m{^/adm/wrapper/ext/}) {
+ $suppanchor = $env{'form.anchor'};
+ }
my $esc_path=&escape(&HTML::Entities::encode(&escape($env{'form.folderpath'}),'<>&"'));
&switch('','',7,4,'docs-22x22.png','Edit Folder','parms[_2]',
- "location.href='/adm/coursedocs?command=direct&forcesupplement=1&supppath=$esc_path'",
+ "location.href='/adm/coursedocs?command=direct&forcesupplement=1&supppath=$esc_path&anchor=$suppanchor'",
'Folder/Page Content','','',1);
}
}
@@ -2283,16 +2360,16 @@ sub roles_selector {
my ($cdom,$cnum,$httphost) = @_;
my $crstype = &Apache::loncommon::course_type();
my $now = time;
- my (%courseroles,%seccount,%courseprivs);
+ my (%courseroles,%seccount,%courseprivs,%roledesc);
my $is_cc;
- my ($js,$form,$switcher,$switchtext);
+ my ($js,$form,$switcher);
my $ccrole;
if ($crstype eq 'Community') {
$ccrole = 'co';
} else {
$ccrole = 'cc';
}
- my ($priv,$gotsymb,$destsymb);
+ my ($privref,$gotsymb,$destsymb);
my $destinationurl = $ENV{'REQUEST_URI'};
if ($destinationurl =~ /\?symb=/) {
$gotsymb = 1;
@@ -2313,12 +2390,15 @@ sub roles_selector {
my $destination = $destinationurl;
$destination =~ s/(\?.*)$//;
if (exists($reqprivs->{$destination})) {
- $priv = $reqprivs->{$destination};
+ if ($reqprivs->{$destination} =~ /,/) {
+ @{$privref} = split(/,/,$reqprivs->{$destination});
+ } else {
+ $privref = [$reqprivs->{$destination}];
+ }
}
}
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))) {
@@ -2328,7 +2408,9 @@ sub roles_selector {
}
}
if ($is_cc) {
- &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,$priv);
+ &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs);
+ } elsif ($env{'request.role'} =~ m{^\Qcr/$cdom/$cdom-domainconfig/\E(\w+)\.\Q/$cdom/$cnum\E}) {
+ &get_customadhoc_roles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,\%roledesc,$privref);
} else {
my %gotnosection;
foreach my $item (keys(%env)) {
@@ -2344,7 +2426,7 @@ sub roles_selector {
$gotnosection{$role} = 1;
}
}
- if ($priv ne '') {
+ if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0)) {
my $cnumsec = $cnum;
if ($sec ne '') {
$cnumsec .= "/$sec";
@@ -2373,7 +2455,6 @@ sub roles_selector {
}
}
}
- $switchtext = 'Switch role'; # do not translate here
my @roles_order = ($ccrole,'in','ta','ep','ad','st');
my $numdiffsec;
if (keys(%seccount) == 1) {
@@ -2383,7 +2464,7 @@ sub roles_selector {
}
if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {
my @submenu;
- $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,$priv);
+ $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,\%roledesc,$privref);
$form =
'