--- loncom/interface/lonmenu.pm 2011/01/27 14:38:44 1.346 +++ loncom/interface/lonmenu.pm 2012/05/21 16:24:14 1.372 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines to control the menu # -# $Id: lonmenu.pm,v 1.346 2011/01/27 14:38:44 wenzelju Exp $ +# $Id: lonmenu.pm,v 1.372 2012/05/21 16:24:14 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -26,8 +26,6 @@ # http://www.lon-capa.org/ # # -# There is one parameter controlling the action of this module: -# =head1 NAME @@ -35,7 +33,8 @@ Apache::lonmenu =head1 SYNOPSIS -Coordinates the response to clicking an image. +Loads contents of /home/httpd/lonTabs/mydesk.tab, +used to generate inline menu, and Main Menu page. This is part of the LearningOnline Network with CAPA project described at http://www.lon-capa.org. @@ -74,10 +73,19 @@ It is set to 'done' in the BEGIN block o =item @primary_menu The elements of this array reference arrays that are made up of the components -of those lines of mydesk.tab that start with prim. +of those lines of mydesk.tab that start with prim:. It is used by primary_menu() to generate the corresponding menu. It gets filled in the BEGIN block of this module. +=item %primary_sub_menu + +The keys of this hash reference are the names of items in the primary_menu array +which have sub-menus. For each key, the corresponding value is a reference to +an array containing components extracted from lines in mydesk.tab which begin +with primsub:. +This hash, which is used by primary_menu to generate sub-menus, is populated in +the BEGIN block. + =item @secondary_menu The elements of this array reference arrays that are made up of the components @@ -129,6 +137,9 @@ The javascript is usually similar to "go =item utilityfunctions() +Output from this routine is a number of javascript functions called by +items in the inline menu, and in some cases items in the Main Menu page. + =item serverform() =item constspaceform() @@ -153,12 +164,13 @@ use Apache::lonhtmlcommon(); use Apache::loncommon(); use Apache::lonenc(); use Apache::lonlocal; +use Apache::lonmsg(); use LONCAPA qw(:DEFAULT :match); use HTML::Entities(); use Apache::lonwishlist(); use vars qw(@desklines %category_names %category_members %category_positions - $readdesk @primary_menu @secondary_menu); + $readdesk @primary_menu %primary_submenu @secondary_menu); my @inlineremote; @@ -181,7 +193,7 @@ sub prep_menuitem { # primary_menu() evaluates @primary_menu and returns XHTML for the menu # that contains following links: -# About, Message, Roles, Help, Logout +# About, Message, Personal, Roles, Help, Logout # @primary_menu is filled within the BEGIN block of this module with # entries from mydesk.tab sub primary_menu { @@ -211,8 +223,54 @@ sub primary_menu { next if $$menuitem[4] eq 'courses' ##'Roles' wanted && !&Apache::loncommon::show_course(); ## - - if ($$menuitem[3] eq 'Help') { # special treatment for helplink + my $title = $menuitem->[3]; + if (defined($primary_submenu{$title})) { + my ($link,$target,$numsub); + if ($menuitem->[0] ne '') { + $link = $menuitem->[0]; + $target = '_top'; + } else { + $link = '#'; + } + if (ref($primary_submenu{$title}) eq 'ARRAY') { + $numsub = @{$primary_submenu{$title}}; + if ($numsub) { + $title = + '<span class="LC_nobreak">'.$title. + '<span class="LC_fontsize_small">'. + '▼</span></span>'; + } + } + $menu .= '<li class="LC_hoverable">'. + '<a href="'.$link.'" target="'.$target.'">'.$title.'</a>'; + if ($numsub) { + $menu .= '<ul>'; + foreach my $item (@{$primary_submenu{$menuitem->[3]}}) { + if (ref($item) eq 'ARRAY') { + if ($item->[2] eq 'wishlist') { + next unless ((&Apache::lonnet::allowed('bre',"/res/$env{'user.domain'}/")) || + (&Apache::lonnet::allowed('bro',"/res/$env{'user.domain'}/"))); + } elsif ($item->[2] eq 'reqcrs') { + next unless(&check_for_rcrs()); + } elsif (($item->[2] eq 'portfolio') || + ($item->[2] eq 'blog')) { + if (!&Apache::lonnet::usertools_access( + $env{'user.name'}, + $env{'user.domain'}, + $item->[2],undef,'tools')) { + next; + } + } + $menu .= '<li style="margin:0;padding:0">'. + '<a href="'.$item->[0]. + '" style="padding:0 0 0 10px">'. + $item->[1].'</a></li>'; + } + } + $menu .= '</ul>'; + } + $menu .= '</li>'; + } elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink if ($public) { my $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'}; my $defdom = &Apache::lonnet::default_login_domain(); @@ -334,9 +392,8 @@ sub secondary_menu { and ( $env{'request.noversionuri'} eq '' || !defined($env{'request.noversionuri'}))) { - ($escurl = $env{'request.filename'}) =~ - s{^/home/([^/]+)/public_html/(.*)$}{/priv/$1/$2}; - + my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{}; $escurl = &escape($escurl); } $menu =~ s/\[url\]/$escurl/g; @@ -359,9 +416,10 @@ sub innerregister { undef(@inlineremote); + my $resurl; if ( $env{'request.symb'} && $env{'request.course.id'} ) { - my ($mapurl,$rid,$resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread()); + (my $mapurl, my $rid, $resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread()); my $coursetitle = $env{'course.'.$env{'request.course.id'}.'.description'}; my $maptitle = &Apache::lonnet::gettitle($mapurl); @@ -410,7 +468,7 @@ sub innerregister { my $hwkadd=''; if ($env{'request.symb'} ne '' && - $env{'request.filename'}=~/\.(problem|exam|quiz|assess|survey|form|task)$/) { + $env{'request.filename'}=~/$LONCAPA::assess_re/) { if (&Apache::lonnet::allowed('mgr',$crs)) { $hwkadd.=&switch('','',7,2,'pgrd.png','Content Grades','grades[_4]', "gocmd('/adm/grades','gradingmenu')", @@ -427,6 +485,12 @@ sub innerregister { "gocmd('/adm/parmset','set')", 'Content Settings'); } + if ($env{'request.symb'}=~/^uploaded/ && + &Apache::lonnet::allowed('mdc',$crs)) { + $hwkadd.=&switch('','',7,4,'docs.png','Folder/Page Content','parms[_2]', + "gocmd('/adm/coursedocs','direct')", + 'Folder/Page Content'); + } # -- End Homework ### ### Determine whether or not to display the 'cstr' button for this @@ -446,7 +510,7 @@ sub innerregister { # # Set defaults for authors my ($top,$bottom) = ('con-','struct'); - my $action = "go('/priv/".$env{'user.name'}."');"; + my $action = "go('/priv/".$env{'user.domain'}.'/'.$env{'user.name'}."');"; my $cadom = $env{'request.role.domain'}; my $caname = $env{'user.name'}; my $desc = "Enter my construction space"; @@ -454,12 +518,12 @@ sub innerregister { if ($env{'request.role'} =~ /^ca/) { ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/); ($top,$bottom) = ('co con-','struct'); - $action = "go('/priv/".$caname."');"; + $action = "go('/priv/".$cadom.'/'.$caname."');"; $desc = "Enter construction space as co-author"; } elsif ($env{'request.role'} =~ /^aa/) { ($cadom,$caname)=($env{'request.role'}=~/($match_domain)\/($match_username)$/); ($top,$bottom) = ('co con-','struct'); - $action = "go('/priv/".$caname."');"; + $action = "go('/priv/".$cadom.'/'.$caname."');"; $desc = "Enter construction space as assistant co-author"; } # Check that we are on the correct machine @@ -492,9 +556,13 @@ sub innerregister { $uploaded = &is_course_upload($file,$cnum,$cdom); } if (!$uploaded) { - $file=~s/^($match_domain)\/($match_username)/\/priv\/$2/; + + $file=~s{^(priv/$match_domain/$match_username)}{/$1}; + $file=~s{^($match_domain/$match_username)}{/priv/$1}; + # Check that the user has permission to edit this resource - ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$1); + my $setpriv = 1; + ($cfuname,$cfudom)=&Apache::loncacc::constructaccess($file,$setpriv); if (defined($cfudom)) { $home=&Apache::lonnet::homeserver($cfuname,$cfudom); my $allowed=0; @@ -555,6 +623,18 @@ sub innerregister { } } } + if ($env{'request.course.id'}) { + if ($resurl eq "public/$cdom/$cnum/syllabus") { + if ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ /\w/) { + if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) { + $editbutton=&switch('','',6,1,'pcstr.png','Edit', + 'resource[_2]', + "go('/adm/courseprefs?phase=display&actions=courseinfo')", + 'Edit this resource'); + } + } + } + } ### ### # Prepare the rest of the buttons @@ -563,9 +643,11 @@ sub innerregister { # # We are in construction space # - my ($uname,$thisdisfn) = - ($env{'request.filename'}=~m|^/home/([^/]+)/public_html/(.*)|); - my $currdir = '/priv/'.$uname.'/'.$thisdisfn; + + my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + my ($udom,$uname,$thisdisfn) = + ($env{'request.filename'}=~m{^\Q$londocroot/priv/\E([^/]+)/([^/]+)/(.*)$}); + my $currdir = '/priv/'.$udom.'/'.$uname.'/'.$thisdisfn; if ($currdir =~ m-/$-) { $is_const_dir = 1; } else { @@ -577,10 +659,10 @@ sub innerregister { # $menuitems=(<<ENDMENUITEMS); s&6&1&list.png&Directory&dir[_1]&golist('$esc_currdir')&List current directory -s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/~$uname/$cleandisfn')&Retrieve old version -s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/~$uname/$cleandisfn')&Publish this resource -s&7&1&del.png&Delete&resource[_2]&gocstr('/adm/cfile?action=delete','/~$uname/$cleandisfn')&Delete this resource -s&7&2&prt.png&Print&printout[_1]&gocstr('/adm/printout','/~$uname/$cleandisfn')&Prepare a printable document +s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/priv/$udom/$uname/$cleandisfn')&Retrieve old version +s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/priv/$udom/$uname/$cleandisfn')&Publish this resource +s&7&1&del.png&Delete&resource[_2]&gocstr('/adm/cfile?action=delete','/priv/$udom/$uname/$cleandisfn')&Delete this resource +s&7&2&prt.png&Print&printout[_1]&gocstr('/adm/printout','/priv/$udom/$uname/$cleandisfn')&Prepare a printable document ENDMENUITEMS } if (ref($bread_crumbs) eq 'ARRAY') { @@ -608,7 +690,7 @@ ENDMENUITEMS # wishlist is only available for users with access to resource-pool # and links can only be set for resources within the resource-pool $menuitems .= (<<ENDMENUITEMS); -s&9&1&wishlist-link.png&Wishlist&wishlistlink[_2]&set_wishlistlink()&Set a link for this resource to wishlist&&1 +s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in your personal Stored Links repository&&1 ENDMENUITEMS } @@ -643,7 +725,7 @@ ENDMENUITEMS if (&Apache::lonnet::allowed('bre', $env{'request.course.id'}) eq 'F') { # wishlist is only available for users with access to resource-pool $menuitems .= (<<ENDMENUITEMS); -s&9&1&wishlist-link.png&Wishlist&wishlistlink[_2]&set_wishlistlink()&Set a link for this resource to wishlist&&1 +s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in in your personal Stored Links repository&&1 ENDMENUITEMS } } @@ -682,15 +764,15 @@ ENDMENUITEMS #publish button in construction space if ($env{'request.state'} eq 'construct'){ &Apache::lonhtmlcommon::add_breadcrumb_tool( - 'advtools', @inlineremote[63]); + 'advtools', $inlineremote[63]); } else { &Apache::lonhtmlcommon::add_breadcrumb_tool( - 'tools', @inlineremote[63]); + 'tools', $inlineremote[63]); } unless ($env{'request.noversionuri'}=~ m{^/adm/(navmaps|viewclasslist)(\?|$)}) { &Apache::lonhtmlcommon::add_breadcrumb_tool( - 'advtools', @inlineremote[61,71,72,73,92]); + 'advtools', @inlineremote[61,71,72,73,74,92]); } } } @@ -988,6 +1070,7 @@ sub rawconfig { ($env{'request.role'}=~/($match_domain)\/($match_username)$/); } $act =~ s/\$caname/$caname/g; + $act =~ s/\$cadom/$cadom/g; my $home = &Apache::lonnet::homeserver($caname,$cadom); my $allowed=0; my @ids=&Apache::lonnet::current_machine_ids(); @@ -1061,13 +1144,13 @@ function showCourseID() { document.getElementById('dccid').style.display='block'; document.getElementById('dccid').style.textAlign='left'; document.getElementById('dccid').style.textFace='normal'; - document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();">$lt{'less'}</a>'; + document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();" class="LC_menubuttons_link">$lt{'less'}</a>'; return; } function hideCourseID() { document.getElementById('dccid').style.display='none'; - document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()">$lt{'more'}</a>'; + document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()" class="LC_menubuttons_link">$lt{'more'}</a>'; return; } @@ -1106,16 +1189,14 @@ sub utilityfunctions { my $confirm_switch = &mt("Editing requires switching to the resource's home server.").'\n'. &mt('Switch server?'); - my $wishlistpopup; - if (&Apache::lonwishlist::getWishlist() ne 'error') { - $wishlistpopup = &Apache::lonwishlist::makePopUpNewLink(); - } + my $esc_url=&escape($currenturl); + my $esc_symb=&escape($currentsymb); return (<<ENDUTILITY) - var currentURL="$currenturl"; - var reloadURL="$currenturl"; - var currentSymb="$currentsymb"; + var currentURL=unescape("$esc_url"); + var reloadURL=unescape("$esc_url"); + var currentSymb=unescape("$esc_symb"); $dc_popup_cid @@ -1208,7 +1289,7 @@ function golist(url) { function catalog_info() { - loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no'); + openMyModal(window.location.pathname+'.meta',500,400,'yes'); } function chat_win() { @@ -1234,11 +1315,7 @@ function annotate() { annotator.document.close(); } -function set_wishlistlink(title, path) { - $wishlistpopup -} - -function open_Wishlist_Import(rat) { +function open_StoredLinks_Import(rat) { var newWin; if (rat) { newWin = window.open('/adm/wishlist?inhibitmenu=yes&mode=import&rat='+rat, @@ -1251,6 +1328,20 @@ function open_Wishlist_Import(rat) { newWin.focus(); } +(function (\$) { + \$(document).ready(function () { + \$.single=function(a){return function(b){a[0]=b;return a}}(\$([1])); + /*\@cc_on + if (!window.XMLHttpRequest) { + \$('.LC_hoverable').each(function () { + this.attachEvent('onmouseenter', function (evt) { \$.single(evt.srcElement).addClass('hover'); }); + this.attachEvent('onmouseleave', function (evt) { \$.single(evt.srcElement).removeClass('hover'); }); + }); + } + \@*/ + }); +}(jQuery)); + ENDUTILITY } @@ -1297,7 +1388,7 @@ sub roles_selector { my ($cdom,$cnum) = @_; my $crstype = &Apache::loncommon::course_type(); my $now = time; - my (%courseroles,%seccount); + my (%courseroles,%seccount,%courseprivs); my $is_cc; my $role_selector; my $ccrole; @@ -1305,7 +1396,17 @@ sub roles_selector { $ccrole = 'co'; } else { $ccrole = 'cc'; - } + } + my $priv; + my $destinationurl = $ENV{'REQUEST_URI'}; + my $reqprivs = &required_privs(); + if (ref($reqprivs) eq 'HASH') { + my $destination = $destinationurl; + $destination =~ s/(\?.*)$//; + if (exists($reqprivs->{$destination})) { + $priv = $reqprivs->{$destination}; + } + } if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) { my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}); @@ -1318,7 +1419,7 @@ sub roles_selector { } } if ($is_cc) { - &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount); + &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,$priv); } else { my %gotnosection; foreach my $item (keys(%env)) { @@ -1334,6 +1435,18 @@ sub roles_selector { $gotnosection{$role} = 1; } } + if ($priv ne '') { + my $cnumsec = $cnum; + if ($sec ne '') { + $cnumsec .= "/$sec"; + } + $courseprivs{"$role./$cdom/$cnumsec./"} = + $env{"user.priv.$role./$cdom/$cnumsec./"}; + $courseprivs{"$role./$cdom/$cnumsec./$cdom/"} = + $env{"user.priv.$role./$cdom/$cnumsec./$cdom/"}; + $courseprivs{"$role./$cdom/$cnumsec./$cdom/$cnumsec"} = + $env{"user.priv.$role./$cdom/$cnumsec./$cdom/$cnumsec"}; + } if (ref($courseroles{$role}) eq 'ARRAY') { if ($sec ne '') { if (!grep(/^\Q$sec\E$/,@{$courseroles{$role}})) { @@ -1359,7 +1472,7 @@ sub roles_selector { } my @roles_order = ($ccrole,'in','ta','ep','ad','st'); if (keys(%courseroles) > 1) { - $role_selector = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles); + $role_selector = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,$priv); $role_selector .= '<form name="rolechooser" method="post" action="/adm/roles"> <select name="switchrole" onchange="javascript:adhocRole('."'switchrole'".')">'; $role_selector .= '<option value="">'.$switchtext.'</option>'; @@ -1375,7 +1488,7 @@ sub roles_selector { } $role_selector .= '</select>'."\n". '<input type="hidden" name="destinationurl" value="'. - &HTML::Entities::encode($ENV{'REQUEST_URI'}).'" />'."\n". + &HTML::Entities::encode($destinationurl).'" />'."\n". '<input type="hidden" name="gotorole" value="1" />'."\n". '<input type="hidden" name="selectrole" value="" />'."\n". '<input type="hidden" name="switch" value="1" />'."\n". @@ -1385,8 +1498,9 @@ sub roles_selector { } sub get_all_courseroles { - my ($cdom,$cnum,$courseroles,$seccount) = @_; - unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH')) { + my ($cdom,$cnum,$courseroles,$seccount,$courseprivs) = @_; + unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH') && + (ref($courseprivs) eq 'HASH')) { return; } my ($result,$cached) = @@ -1394,9 +1508,11 @@ sub get_all_courseroles { if (defined($cached)) { if (ref($result) eq 'HASH') { if ((ref($result->{'roles'}) eq 'HASH') && - (ref($result->{'seccount'}) eq 'HASH')) { + (ref($result->{'seccount'}) eq 'HASH') && + (ref($result->{'privs'}) eq 'HASH')) { %{$courseroles} = %{$result->{'roles'}}; %{$seccount} = %{$result->{'seccount'}}; + %{$courseprivs} = %{$result->{'privs'}}; return; } } @@ -1424,30 +1540,43 @@ sub get_all_courseroles { push(@{$courseroles->{$urole}},$usec); } } + my $area = '/'.$cdom.'/'.$cnum; + if ($usec ne '') { + $area .= '/'.$usec; + } + if ($role =~ /^cr\//) { + &Apache::lonnet::custom_roleprivs($courseprivs,$urole,$cdom,$cnum,$urole.'.'.$area,$area); + } else { + &Apache::lonnet::standard_roleprivs($courseprivs,$urole,$cdom,$urole.'.'.$area,$cnum,$area); + } } my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum,['st']); @{$courseroles->{'st'}} = (); + &Apache::lonnet::standard_roleprivs($courseprivs,'st',$cdom,"st./$cdom/$cnum",$cnum,"/$cdom/$cnum"); if (keys(%sections_count) > 0) { push(@{$courseroles->{'st'}},keys(%sections_count)); - $seccount->{'st'} = scalar(keys(%sections_count)); + $seccount->{'st'} = scalar(keys(%sections_count)); } my $rolehash = { 'roles' => $courseroles, 'seccount' => $seccount, + 'privs' => $courseprivs, }; &Apache::lonnet::do_cache_new('getcourseroles',$cdom.'_'.$cnum,$rolehash); return; } sub jump_to_role { - my ($cdom,$cnum,$seccount,$courseroles) = @_; + my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$priv) = @_; my %lt = &Apache::lonlocal::texthash( this => 'This role has section(s) associated with it.', ente => 'Enter a specific section.', orlb => 'Enter a specific section, or leave blank for no section.', avai => 'Available sections are:', youe => 'You entered an invalid section choice:', - plst => 'Please try again', + plst => 'Please try again.', + role => 'The role you selected is not permitted to view the current page.', + swit => 'Switch role, but display Main Menu page instead?', ); my $js; if (ref($courseroles) eq 'HASH') { @@ -1470,6 +1599,37 @@ sub jump_to_role { ' numsec['.$i.'] = "'.$seccount->{$items[$i]}.'";'."\n"; } } + my $checkroles = 0; + if ($priv && ref($courseprivs) eq 'HASH') { + my (%disallowed,%allowed,@disallow); + foreach my $role (sort(keys(%{$courseprivs}))) { + my $trole; + if ($role =~ m{^(.+?)\Q./$cdom/$cnum\E}) { + $trole = $1; + } + if (($trole ne '') && ($trole ne 'cm')) { + if ($courseprivs->{$role} =~ /\Q:$priv\E($|:|\&\w+)/) { + $allowed{$trole} = 1; + } else { + $disallowed{$trole} = 1; + } + } + } + foreach my $trole (keys(%disallowed)) { + unless ($allowed{$trole}) { + push(@disallow,$trole); + } + } + if (@disallow > 0) { + $checkroles = 1; + $js .= " var disallow = new Array('".join("','",@disallow)."');\n". + " var rolecheck = 1;\n"; + } + } + if (!$checkroles) { + $js .= " var disallow = new Array();\n". + " rolecheck = 0;\n"; + } return <<"END"; <script type="text/javascript"> //<![CDATA[ @@ -1477,7 +1637,7 @@ function adhocRole(roleitem) { $js var newrole = document.rolechooser.elements[roleitem].options[document.rolechooser.elements[roleitem].selectedIndex].value; if (newrole == '') { - return; + return; } var fullrole = newrole+'./$cdom/$cnum'; var selidx = ''; @@ -1486,6 +1646,18 @@ function adhocRole(roleitem) { selidx = i; } } + if (rolecheck > 0) { + for (var i=0; i<disallow.length; i++) { + if (disallow[i] == newrole) { + if (confirm("$lt{'role'}\\n$lt{'swit'}")) { + document.rolechooser.destinationurl.value = '/adm/menu'; + } else { + document.rolechooser.elements[roleitem].selectedIndex = 0; + return; + } + } + } + } var secok = 1; var secchoice = ''; if (selidx >= 0) { @@ -1523,6 +1695,7 @@ function adhocRole(roleitem) { return; } if (fullrole == "$env{'request.role'}") { + document.rolechooser.elements[roleitem].selectedIndex = 0; return; } itemid = retrieveIndex('gotorole'); @@ -1548,6 +1721,24 @@ function retrieveIndex(item) { END } +sub required_privs { + my $privs = { + '/adm/parmset' => 'opa', + '/adm/courseprefs' => 'opa', + '/adm/whatsnew' => 'whn', + '/adm/populate' => 'cst', + '/adm/trackstudent' => 'vsa', + '/adm/statistics' => 'vgr', + '/adm/setblock' => 'dcm', + '/adm/coursedocs' => 'mdc', + }; + unless ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet') { + $privs->{'/adm/classcalc'} = 'vgr', + $privs->{'/adm/assesscalc'} = 'vgr', + $privs->{'/adm/studentcalc'} = 'vgr'; + } + return $privs; +} # ================================================================ Main Program @@ -1567,6 +1758,9 @@ BEGIN { } elsif ($configline=~/^prim\:/) { my @entries = (split(/\:/, $configline))[1..5]; push @primary_menu, \@entries; + } elsif ($configline=~/^primsub\:/) { + my ($parent,@entries) = (split(/\:/, $configline))[1..4]; + push (@{$primary_submenu{$parent}},\@entries); } elsif ($configline=~/^scnd\:/) { my @entries = (split(/\:/, $configline))[1..5]; push @secondary_menu, \@entries;