Annotation of loncom/interface/lonmenu.pm, revision 1.475

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Routines to control the menu
                      3: #
1.475   ! raeburn     4: # $Id: lonmenu.pm,v 1.474 2017/08/21 21:13:09 raeburn Exp $
1.11      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: #
                     29: 
1.244     jms        30: =head1 NAME
                     31: 
                     32: Apache::lonmenu
                     33: 
                     34: =head1 SYNOPSIS
                     35: 
1.371     raeburn    36: Loads contents of /home/httpd/lonTabs/mydesk.tab, 
                     37: used to generate inline menu, and Main Menu page. 
1.244     jms        38: 
                     39: This is part of the LearningOnline Network with CAPA project
                     40: described at http://www.lon-capa.org.
                     41: 
1.314     droeschl   42: =head1 GLOBAL VARIABLES
                     43: 
                     44: =over
                     45: 
                     46: =item @desklines
                     47: 
                     48: Each element of this array contains a line of mydesk.tab that doesn't start with
                     49: cat, prim or scnd. 
                     50: It gets filled in the BEGIN block of this module.
                     51: 
                     52: =item %category_names
                     53: 
                     54: The keys of this hash are the abbreviations used in mydesk.tab in those lines that 
                     55: start with cat, the values are strings representing titles. 
                     56: It gets filled in the BEGIN block of this module.
                     57: 
                     58: =item %category_members
                     59: 
                     60: TODO 
                     61: 
                     62: =item %category_positions
                     63: 
                     64: The keys of this hash are the abbreviations used in mydesk.tab in those lines that
                     65: start with cat, its values are position vectors (column, row). 
                     66: It gets filled in the BEGIN block of this module.
                     67: 
                     68: =item $readdesk
                     69: 
                     70: Indicates that mydesk.tab has been read. 
                     71: It is set to 'done' in the BEGIN block of this module.
                     72: 
                     73: =item @primary_menu
                     74: 
                     75: The elements of this array reference arrays that are made up of the components
1.371     raeburn    76: of those lines of mydesk.tab that start with prim:.
1.314     droeschl   77: It is used by primary_menu() to generate the corresponding menu.
                     78: It gets filled in the BEGIN block of this module.
                     79: 
1.371     raeburn    80: =item %primary_sub_menu
                     81: 
                     82: The keys of this hash reference are the names of items in the primary_menu array 
                     83: which have sub-menus.  For each key, the corresponding value is a reference to
                     84: an array containing components extracted from lines in mydesk.tab which begin
                     85: with primsub:.
                     86: This hash, which is used by primary_menu to generate sub-menus, is populated in
                     87: the BEGIN block.
                     88: 
1.314     droeschl   89: =item @secondary_menu
                     90: 
                     91: The elements of this array reference arrays that are made up of the components
                     92: of those lines of mydesk.tab that start with scnd.
                     93: It is used by secondary_menu() to generate the corresponding menu.
                     94: It gets filled in the BEGIN block of this module.
                     95: 
                     96: =back
                     97: 
1.244     jms        98: =head1 SUBROUTINES
                     99: 
                    100: =over
                    101: 
1.314     droeschl  102: =item prep_menuitems(\@menuitem)
                    103: 
                    104: This routine wraps a menuitem in proper HTML. It is used by primary_menu() and 
                    105: secondary_menu().
                    106: 
                    107: =item primary_menu()
                    108: 
1.415     raeburn   109: This routine evaluates @primary_menu and returns a two item array, 
                    110: with the array elements containing XHTML for the left and right sides of 
                    111: the menu that contains the following links: About, Message, Roles, Help, Logout 
1.314     droeschl  112: @primary_menu is filled within the BEGIN block of this module with 
1.415     raeburn   113: entries from mydesk.tab
1.314     droeschl  114: 
                    115: =item secondary_menu()
                    116: 
                    117: Same as primary_menu() but operates on @secondary_menu.
                    118: 
1.375     raeburn   119: =item create_submenu()
                    120: 
                    121: Creates XHTML for unordered list of sub-menu items which belong to a 
                    122: particular top-level menu item. Uses hover pseudo class in css to display
                    123: dropdown list when mouse hovers over top-level item. Support for IE6 
                    124: (no hover psuedo class) via LC_hoverable class for <li> tag for top-
                    125: level item, which employs jQuery to handle behavior on mouseover.
                    126: 
1.447     raeburn   127: Inputs: 6 - (a) link and (b) target for anchor href in top level item,
                    128:             (c) title for text wrapped by anchor tag in top level item,
                    129:             (d) reference to array of arrays of sub-menu items,
                    130:             (e) boolean to indicate whether to call &mt() to translate 
                    131:                 name of menu item,
                    132:             (f) optional class for <li> element in primary menu, for which
                    133:                 sub menu is being generated.
1.375     raeburn   134: 
1.431     golterma  135:  The underlying datastructure used in (d) contains data from mydesk.tab.
                    136:  It consists of an array which has an array for each item appearing in
                    137:  the menu (e.g. [["link", "title", "condition"]] for a single-item menu).
                    138:  create_submenu() supports also the creation of XHTML for nested dropdown
                    139:  menus represented by unordered lists. This is done by replacing the
                    140:  scalar used for the link with an arrayreference containing the menuitems
                    141:  for the nested menu. This can be done recursively so that the next menu
                    142:  may also contain nested submenus.
                    143: 
                    144:  Example:
                    145:  [											# begin of datastructure
                    146: 	["/home/", "Home", "condition1"], 		# 1st item of the 1st layer menu
                    147: 	[										# 2nd item of the 1st layer menu
                    148: 		[									# anon. array for nested menu
                    149: 			["/path1", "Path1", undef], 	# 1st item of the 2nd layer menu
                    150: 			["/path2", "Path2", undef], 	# 2nd item of the 2nd layer menu
                    151: 			[								# 3rd item of the 2nd layer menu
                    152: 				[[...], [...], ..., [...]],	# containing another menu layer
                    153: 				"Sub-Sub-Menu",				# title for this container
                    154: 				undef
                    155: 			]
                    156: 		],									# end of array/nested menu
                    157: 		"Sub-Menu",							# title for the container item
                    158: 		undef
                    159: 	]										# end of 2nd item of the 1st layer menu
                    160: ]
                    161: 
1.244     jms       162: =item innerregister()
                    163: 
1.320     droeschl  164: This gets called in order to register a URL in the body of the document
1.244     jms       165: 
                    166: =item clear()
                    167: 
                    168: =item switch()
                    169: 
                    170: Switch a button or create a link
                    171: Switch acts on the javascript that is executed when a button is clicked.  
                    172: The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
                    173: 
                    174: =item secondlevel()
                    175: 
                    176: =item openmenu()
                    177: 
                    178: =item inlinemenu()
                    179: 
                    180: =item rawconfig()
                    181: 
                    182: =item utilityfunctions()
                    183: 
1.371     raeburn   184: Output from this routine is a number of javascript functions called by
                    185: items in the inline menu, and in some cases items in the Main Menu page. 
                    186: 
1.244     jms       187: =item serverform()
                    188: 
                    189: =item constspaceform()
                    190: 
                    191: =item get_nav_status()
                    192: 
                    193: =item hidden_button_check()
                    194: 
                    195: =item roles_selector()
                    196: 
                    197: =item jump_to_role()
                    198: 
                    199: =back
                    200: 
                    201: =cut
                    202: 
1.1       www       203: package Apache::lonmenu;
                    204: 
                    205: use strict;
1.152     albertel  206: use Apache::lonnet;
1.47      matthew   207: use Apache::lonhtmlcommon();
1.115     albertel  208: use Apache::loncommon();
1.127     albertel  209: use Apache::lonenc();
1.88      www       210: use Apache::lonlocal;
1.361     raeburn   211: use Apache::lonmsg();
1.207     foxr      212: use LONCAPA qw(:DEFAULT :match);
1.282     amueller  213: use HTML::Entities();
1.346     wenzelju  214: use Apache::lonwishlist();
1.88      www       215: 
1.283     droeschl  216: use vars qw(@desklines %category_names %category_members %category_positions 
1.371     raeburn   217:             $readdesk @primary_menu %primary_submenu @secondary_menu);
1.88      www       218: 
1.56      www       219: my @inlineremote;
1.38      www       220: 
1.283     droeschl  221: sub prep_menuitem {
1.291     raeburn   222:     my ($menuitem) = @_;
                    223:     return '' unless(ref($menuitem) eq 'ARRAY');
1.283     droeschl  224:     my $link;
                    225:     if ($$menuitem[1]) { # graphical Link
                    226:         $link = "<img class=\"LC_noBorder\""
1.291     raeburn   227:               . " src=\"" . &Apache::loncommon::lonhttpdurl($$menuitem[1]) . "\"" 
                    228:               . " alt=\"" . &mt($$menuitem[2]) . "\" />";
1.283     droeschl  229:     } else {             # textual Link
1.291     raeburn   230:         $link = &mt($$menuitem[3]);
                    231:     }
1.316     droeschl  232:     return '<li><a' 
                    233:            # highlighting for new messages
                    234:            . ( $$menuitem[4] eq 'newmsg' ? ' class="LC_new_message"' : '') 
1.325     droeschl  235:            . qq| href="$$menuitem[0]" target="_top">$link</a></li>|;
1.283     droeschl  236: }
                    237: 
1.415     raeburn   238: # primary_menu() evaluates @primary_menu and returns a two item array,
                    239: # with the array elements containing XHTML for the left and right sides of 
                    240: # the menu that contains the following links:
                    241: # Personal, About, Message, Roles, Help, Logout
1.283     droeschl  242: # @primary_menu is filled within the BEGIN block of this module with 
                    243: # entries from mydesk.tab
                    244: sub primary_menu {
1.443     raeburn   245:     my ($crstype) = @_;
1.415     raeburn   246:     my (%menu);
1.283     droeschl  247:     # each element of @primary contains following array:
1.415     raeburn   248:     # (link url, icon path, alt text, link text, condition, position)
1.319     raeburn   249:     my $public;
                    250:     if ((($env{'user.name'} eq 'public') && ($env{'user.domain'} eq 'public'))
                    251:         || (($env{'user.name'} eq '') && ($env{'user.domain'} eq ''))) {
                    252:         $public = 1;
                    253:     }
1.443     raeburn   254:     my $rolecount;
                    255:     if (($crstype eq 'Placement') && (!$env{'request.role.adv'})) {
                    256:         my $update=$env{'user.update.time'};
                    257:         if (!$update) {
                    258:             $update = $env{'user.login.time'};
                    259:         }
                    260:         my %roles_in_env;
                    261:         $rolecount = &Apache::lonroles::roles_from_env(\%roles_in_env,$update);
                    262:     }
1.283     droeschl  263:     foreach my $menuitem (@primary_menu) {
                    264:         # evaluate conditions 
1.296     droeschl  265:         next if    ref($menuitem)       ne 'ARRAY';    #
1.283     droeschl  266:         next if    $$menuitem[4]        eq 'nonewmsg'  # show links depending on
1.291     raeburn   267:                 && &Apache::lonmsg::mynewmail();       # whether a new msg 
1.283     droeschl  268:         next if    $$menuitem[4]        eq 'newmsg'    # arrived or not
1.291     raeburn   269:                 && !&Apache::lonmsg::mynewmail();      # 
1.319     raeburn   270:         next if    $$menuitem[4]        !~ /public/    ##we've a public user,
                    271:                 && $public;                            ##who should not see all
                    272:                                                        ##links
1.283     droeschl  273:         next if    $$menuitem[4]        eq 'onlypublic'# hide links which are 
1.319     raeburn   274:                 && !$public;                           # only visible to public
                    275:                                                        # users
1.283     droeschl  276:         next if    $$menuitem[4]        eq 'roles'     ##show links depending on
1.291     raeburn   277:                 && &Apache::loncommon::show_course();  ##term 'Courses' or 
1.283     droeschl  278:         next if    $$menuitem[4]        eq 'courses'   ##'Roles' wanted
1.291     raeburn   279:                 && !&Apache::loncommon::show_course(); ##
1.371     raeburn   280:         my $title = $menuitem->[3];
1.443     raeburn   281:         if (($crstype eq 'Placement') && (!$env{'request.role.adv'})) {
                    282:             if ($menuitem->[4] eq 'courses') {
                    283:                 next unless ($rolecount>1);
                    284:             } else {
                    285:                 next unless (($title eq 'Personal') || ($title eq 'Logout'));
                    286:             }
                    287:         }
1.415     raeburn   288:         my $position = $menuitem->[5];
                    289:         if ($position eq '') {
                    290:             $position = 'right';
                    291:         }
1.371     raeburn   292:         if (defined($primary_submenu{$title})) {
1.375     raeburn   293:             my ($link,$target);
1.371     raeburn   294:             if ($menuitem->[0] ne '') {
                    295:                 $link = $menuitem->[0];
                    296:                 $target = '_top';
                    297:             } else {
                    298:                 $link = '#';
                    299:             }
1.375     raeburn   300:             my @primsub;
1.371     raeburn   301:             if (ref($primary_submenu{$title}) eq 'ARRAY') {
1.375     raeburn   302:                 foreach my $item (@{$primary_submenu{$title}}) {
1.443     raeburn   303:                     next if (($crstype eq 'Placement') && (!$env{'request.role.adv'}));
1.383     raeburn   304:                     next if (($item->[2] eq 'wishlist') && (!$env{'user.adv'}));
1.375     raeburn   305:                     next if ((($item->[2] eq 'portfolio') ||
                    306:                              ($item->[2] eq 'blog')) &&
                    307:                              (!&Apache::lonnet::usertools_access('','',$item->[2],
                    308:                                                            undef,'tools')));
                    309:                     push(@primsub,$item);
                    310:                 }
1.443     raeburn   311:                 if ($title eq 'Personal' && $env{'user.name'} && $env{'user.domain'} ) {
                    312:                     $title = &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'});
                    313:                 } else {
                    314:                     $title = &mt($title);
                    315:                 }
1.375     raeburn   316:                 if (@primsub > 0) {
1.419     bisitz    317:                     $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1);
1.375     raeburn   318:                 } elsif ($link) {
1.443     raeburn   319:                     $menu{$position} .= '<li><a href="'.$link.'" target="'.$target.'">'.$title.'</a></li>';
1.371     raeburn   320:                 }
                    321:             }
                    322:         } elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink
1.443     raeburn   323:             next if ($crstype eq 'Placement'); 
1.340     raeburn   324:             if ($public) {
                    325:                 my $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};
                    326:                 my $defdom = &Apache::lonnet::default_login_domain();
                    327:                 my $to = &Apache::loncommon::build_recipient_list(undef,
                    328:                                                                   'helpdeskmail',
                    329:                                                                   $defdom,$origmail);
                    330:                 if ($to ne '') {
1.415     raeburn   331:                     $menu{$position} .= &prep_menuitem($menuitem); 
1.340     raeburn   332:                 }
                    333:             } else {
1.415     raeburn   334:                 $menu{$position} .= '<li>'.&Apache::loncommon::top_nav_help('Help').'</li>';
1.340     raeburn   335:             }
1.283     droeschl  336:         } else {
1.415     raeburn   337:             $menu{$position} .= prep_menuitem($menuitem);
1.283     droeschl  338:         }
1.291     raeburn   339:     }
1.423     raeburn   340:     my @output = ('','');
                    341:     if ($menu{'left'} ne '') {
                    342:         $output[0] = "<ol class=\"LC_primary_menu LC_floatleft\">$menu{'left'}</ol>";
                    343:     }
                    344:     if ($menu{'right'} ne '') {
                    345:         $output[1] = "<ol class=\"LC_primary_menu LC_floatright LC_right\">$menu{'right'}</ol>";
                    346:     }
                    347:     return @output;
1.283     droeschl  348: }
                    349: 
1.329     droeschl  350: #returns hashref {user=>'',dom=>''} containing:
                    351: #   own name, domain if user is au
                    352: #   name, domain of parent author if user is ca or aa
                    353: #empty return if user is not an author or not on homeserver
                    354: #
                    355: #TODO this should probably be moved somewhere more central
                    356: #since it can be used by different parts of the system
                    357: sub getauthor{
                    358:     return unless $env{'request.role'}=~/^(ca|aa|au)/; #nothing to do if user isn't some kind of author
                    359: 
                    360:                         #co- or assistent author?
                    361:     my ($dom, $user) = ($env{'request.role'} =~ /^(?:ca|aa)\.\/($match_domain)\/($match_username)$/)
                    362:                        ? ($1, $2) #domain, username of the parent author
                    363:                        : @env{ ('request.role.domain', 'user.name') }; #own domain, username
                    364: 
                    365:     # current server == home server?
                    366:     my $home =  &Apache::lonnet::homeserver($user,$dom);
                    367:     foreach (&Apache::lonnet::current_machine_ids()){
                    368:         return {user => $user, dom => $dom} if $_ eq $home;
                    369:     }
                    370: 
                    371:     # if wrong server
                    372:     return;
                    373: }
1.283     droeschl  374: 
                    375: sub secondary_menu {
1.421     raeburn   376:     my ($httphost) = @_;
1.283     droeschl  377:     my $menu;
                    378: 
1.286     raeburn   379:     my $crstype = &Apache::loncommon::course_type();
1.327     droeschl  380:     my $crs_sec = $env{'request.course.id'} . ($env{'request.course.sec'} 
                    381:                                                ? "/$env{'request.course.sec'}"
                    382:                                                : '');
                    383:     my $canedit       = &Apache::lonnet::allowed('mdc', $env{'request.course.id'});
1.464     raeburn   384:     my $canvieweditor = &Apache::lonnet::allowed('cev', $env{'request.course.id'});
1.376     raeburn   385:     my $canviewroster = $env{'course.'.$env{'request.course.id'}.'.student_classlist_view'};
1.418     raeburn   386:     if ($canviewroster eq 'disabled') {
                    387:         undef($canviewroster);
                    388:     }
1.327     droeschl  389:     my $canviewgrps   = &Apache::lonnet::allowed('vcg', $crs_sec); 
1.453     raeburn   390:     my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);
                    391:     my $canviewusers  = &Apache::lonnet::allowed('vcl', $crs_sec); 
1.327     droeschl  392:     my $canviewwnew   = &Apache::lonnet::allowed('whn', $crs_sec); 
1.454     raeburn   393:     my $canviewpara   = &Apache::lonnet::allowed('vpa', $crs_sec);
1.341     www       394:     my $canmodpara    = &Apache::lonnet::allowed('opa', $crs_sec);
1.343     www       395:     my $canvgr        = &Apache::lonnet::allowed('vgr', $crs_sec);
                    396:     my $canmgr        = &Apache::lonnet::allowed('mgr', $crs_sec); 
                    397:     my $author        = &getauthor();
1.327     droeschl  398: 
1.439     raeburn   399:     my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools);
                    400:     $grouptools = 0;
1.413     raeburn   401:     if ($env{'request.course.id'}) {
                    402:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    403:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.464     raeburn   404:         if ($canedit || $canvieweditor)  {
1.413     raeburn   405:             $showsyllabus = 1;
                    406:             $showfeeds = 1;
                    407:         } else {
1.414     raeburn   408:             unless (&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) {
                    409:                 if (($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) ||
                    410:                     ($env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) ||
                    411:                     ($env{'course.'.$env{'request.course.id'}.'.updatedsyllabus'}) ||
                    412:                     ($env{'request.course.syllabustime'})) {
                    413:                     $showsyllabus = 1;
                    414:                 }
                    415:             }
                    416:             if ($env{'request.course.feeds'}) {
                    417:                 $showfeeds = 1;
1.413     raeburn   418:             }
                    419:         }
1.464     raeburn   420:         unless ($canmgr || $canvgr) {
1.417     raeburn   421:             my %slots = &Apache::lonnet::get_course_slots($cnum,$cdom);
                    422:             if (keys(%slots) > 0) {
                    423:                 $showresv = 1;
                    424:             }
                    425:         }
1.439     raeburn   426:         my %groups = &Apache::lonnet::get_active_groups(
                    427:                      $env{'user.domain'}, $env{'user.name'},$cdom,$cnum);
                    428:         if (%groups) {
                    429:             foreach my $group (keys(%groups)) {
                    430:                 my @privs = split(/:/,$env{"user.priv.$env{'request.role'}./$cdom/$cnum/$group"});
                    431:                 shift(@privs);
                    432:                 if (@privs) {
                    433:                     $grouptools ++;
                    434:                 }
                    435:             }
                    436:         }
1.413     raeburn   437:     }
                    438: 
1.404     raeburn   439:     my ($canmodifycoauthor); 
                    440:     if ($env{'request.role'} eq "au./$env{'user.domain'}/") {
                    441:         my $extent = "$env{'user.domain'}/$env{'user.name'}";
                    442:         if ((&Apache::lonnet::allowed('cca',$extent)) ||
                    443:             (&Apache::lonnet::allowed('caa',$extent))) {
                    444:             $canmodifycoauthor = 1;
                    445:         }
                    446:     }
1.401     raeburn   447:     my ($roleswitcher_js,$roleswitcher_form);
                    448: 
1.283     droeschl  449:     foreach my $menuitem (@secondary_menu) {
                    450:         # evaluate conditions 
1.296     droeschl  451:         next if    ref($menuitem)  ne 'ARRAY';
1.443     raeburn   452:         next if (($crstype eq 'Placement') && ($$menuitem[3] ne 'Roles') && (!$env{'request.role.adv'}));
1.283     droeschl  453:         next if    $$menuitem[4]   ne 'always'
1.404     raeburn   454:                 && ($$menuitem[4]   ne 'author' && $$menuitem[4] ne 'cca')
1.283     droeschl  455:                 && !$env{'request.course.id'};
1.464     raeburn   456:         next if    $$menuitem[4]   =~ /^crsedit/
                    457:                 && (!$canedit && !$canvieweditor);
1.341     www       458:         next if    $$menuitem[4]  eq 'nvgr'
                    459:                 && $canvgr;
                    460:         next if    $$menuitem[4]  eq 'vgr'
                    461:                 && !$canvgr;
1.456     raeburn   462:         next if    $$menuitem[4]   eq 'viewusers'
1.453     raeburn   463:                 && !$canmodifyuser && !$canviewusers;
1.456     raeburn   464:         next if    $$menuitem[4]   eq 'noviewusers'
1.453     raeburn   465:                 && ($canmodifyuser || $canviewusers || !$canviewroster);
1.343     www       466:         next if    $$menuitem[4]   eq 'mgr'
                    467:                 && !$canmgr;
1.417     raeburn   468:         next if    $$menuitem[4]   eq 'showresv'
                    469:                 && !$showresv;
1.327     droeschl  470:         next if    $$menuitem[4]   eq 'whn'
                    471:                 && !$canviewwnew;
1.454     raeburn   472:         next if    $$menuitem[4]   eq 'params'
                    473:                 && (!$canmodpara && !$canviewpara);
1.283     droeschl  474:         next if    $$menuitem[4]   =~ /showgroups$/
1.300     raeburn   475:                 && !$canviewgrps
1.439     raeburn   476:                 && !$grouptools;
1.413     raeburn   477:         next if    $$menuitem[4]   eq 'showsyllabus'
                    478:                 && !$showsyllabus;
                    479:         next if    $$menuitem[4]   eq 'showfeeds'
                    480:                 && !$showfeeds;
1.329     droeschl  481:         next if    $$menuitem[4]    eq 'author'
                    482:                 && !$author;
1.404     raeburn   483:         next if    $$menuitem[4]    eq 'cca'
                    484:                 && !$canmodifycoauthor;
1.283     droeschl  485: 
1.286     raeburn   486:         if ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
1.283     droeschl  487:             # special treatment for role selector
1.401     raeburn   488:             ($roleswitcher_js,$roleswitcher_form,my $switcher) =
                    489:                 &roles_selector(
1.283     droeschl  490:                         $env{'course.' . $env{'request.course.id'} . '.domain'},
1.421     raeburn   491:                         $env{'course.' . $env{'request.course.id'} . '.num'},
                    492:                         $httphost
1.401     raeburn   493:                 );
                    494:             $menu .= $switcher;
1.296     droeschl  495:         } else {
1.414     raeburn   496:             if ($$menuitem[3] eq 'Syllabus' && $env{'request.course.id'}) {
                    497:                 my $url = $$menuitem[0];
                    498:                 $url =~ s{\[cdom\]/\[cnum\]}{$cdom/$cnum};
                    499:                 if (&Apache::lonnet::is_on_map($url)) {
1.468     raeburn   500:                     unless ($$menuitem[0] =~ /(\?|\&)register=1/) {
                    501:                         $$menuitem[0] .= (($$menuitem[0]=~/\?/)? '&' : '?').'register=1';
1.414     raeburn   502:                     }
                    503:                 } else {
1.468     raeburn   504:                     $$menuitem[0] =~ s{\&?register=1}{};
1.414     raeburn   505:                 }
1.468     raeburn   506:                 if ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://}) {
                    507:                     if (($ENV{'SERVER_PORT'} == 443) || ($env{'request.use_absolute'} =~ m{^https://})) {
                    508:                         unless ($$menuitem[0] =~ m{^https?://}) {
                    509:                             $$menuitem[0] = 'http://'.$ENV{'SERVER_NAME'}.$$menuitem[0];
                    510:                         }
                    511:                         unless ($$menuitem[0] =~ /(\&|\?)usehttp=1/) {
                    512:                             $$menuitem[0] .= (($$menuitem[0]=~/\?/) ? '&' : '?').'usehttp=1';
                    513:                         }
                    514:                     }
1.467     raeburn   515:                 }
1.473     raeburn   516:                 $$menuitem[0] = &HTML::Entities::encode($$menuitem[0],'&<>"');
1.414     raeburn   517:             }
1.296     droeschl  518:             $menu .= &prep_menuitem(\@$menuitem);
1.283     droeschl  519:         }
                    520:     }
                    521:     if ($menu =~ /\[url\].*\[symb\]/) {
1.291     raeburn   522:         my $escurl  = &escape( &Apache::lonenc::check_encrypt(
                    523:                              $env{'request.noversionuri'}));
1.283     droeschl  524: 
1.291     raeburn   525:         my $escsymb = &escape( &Apache::lonenc::check_encrypt(
                    526:                              $env{'request.symb'})); 
1.283     droeschl  527: 
                    528:         if (    $env{'request.state'} eq 'construct'
                    529:             and (   $env{'request.noversionuri'} eq '' 
                    530:                  || !defined($env{'request.noversionuri'}))) 
                    531:         {
1.359     raeburn   532:             my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
                    533:             ($escurl = $env{'request.filename'}) =~ s{^\Q$londocroot\E}{};
1.291     raeburn   534:             $escurl  = &escape($escurl);
1.473     raeburn   535:         }
1.283     droeschl  536:         $menu =~ s/\[url\]/$escurl/g;
                    537:         $menu =~ s/\[symb\]/$escsymb/g;
                    538:     }
1.329     droeschl  539:     $menu =~ s/\[uname\]/$$author{user}/g;
                    540:     $menu =~ s/\[udom\]/$$author{dom}/g;
1.413     raeburn   541:     if ($showsyllabus || $showfeeds) {
                    542:         $menu =~ s/\[cnum\]/$cnum/g;
                    543:         $menu =~ s/\[cdom\]/$cdom/g;
                    544:     }
1.385     raeburn   545:     if ($menu) {
                    546:         $menu = "<ul id=\"LC_secondary_menu\">$menu</ul>";
                    547:     }
1.401     raeburn   548:     if ($roleswitcher_form) {
                    549:         $menu .= "\n$roleswitcher_js\n$roleswitcher_form";
                    550:     }
1.385     raeburn   551:     return $menu;
1.283     droeschl  552: }
                    553: 
1.375     raeburn   554: sub create_submenu {
1.447     raeburn   555:     my ($link,$target,$title,$submenu,$translate,$addclass) = @_;
1.375     raeburn   556:     return unless (ref($submenu) eq 'ARRAY');
1.379     raeburn   557:     my $disptarget;
                    558:     if ($target ne '') {
                    559:         $disptarget = ' target="'.$target.'"';
                    560:     }
1.447     raeburn   561:     my $menu = '<li class="LC_hoverable '.$addclass.'">'.
1.379     raeburn   562:                '<a href="'.$link.'"'.$disptarget.'>'.
1.432     droeschl  563:                '<span class="LC_nobreak">'.$title.
1.375     raeburn   564:                '<span class="LC_fontsize_small" style="font-weight:normal;">'.
                    565:                ' &#9660;</span></span></a>'.
                    566:                '<ul>';
1.431     golterma  567: 
                    568:     # $link and $title are only used in the initial string written in $menu
                    569:     # as seen above, not needed for nested submenus
                    570:     $menu .= &build_submenu($target, $submenu, $translate, '1');
                    571:     $menu .= '</ul></li>';
                    572: 
                    573:     return $menu;
                    574: }
                    575: 
                    576: # helper routine for create_submenu
                    577: # build the dropdown (and nested submenus) recursively
                    578: # see perldoc create_submenu documentation for further information
                    579: sub build_submenu {
                    580:     my ($target, $submenu, $translate, $first_level) = @_; 
1.446     raeburn   581:     unless (@{$submenu}) {
1.431     golterma  582:         return '';
                    583:     }
                    584: 
                    585:     my $menu = '';
1.375     raeburn   586:     my $count = 0;
                    587:     my $numsub = scalar(@{$submenu});
                    588:     foreach my $item (@{$submenu}) {
                    589:         $count ++;
                    590:         if (ref($item) eq 'ARRAY') {
1.416     raeburn   591:             my $href = $item->[0];
1.431     golterma  592:             my $bordertop;
                    593:             my $borderbot;
                    594:             my $title;
                    595: 
                    596:             if ($translate) {
                    597:                  $title = &mt($item->[1]);
                    598:             } else {
                    599:                 $title = $item->[1];
                    600:             }
                    601: 
                    602:             if ($count == 1 && !$first_level) {
                    603:                 $bordertop = 'border-top: 1px solid black;';
1.416     raeburn   604:             }
1.375     raeburn   605:             if ($count == $numsub) {
1.431     golterma  606:                 $borderbot = 'border-bottom: 1px solid black;';
1.375     raeburn   607:             }
1.431     golterma  608: 
                    609:             # href is a reference to another submenu
                    610:             if (ref($href) eq 'ARRAY') {
                    611:                 $menu .= '<li style="margin:0;padding:0;'.$bordertop . $borderbot . '">';
                    612:                 $menu .= '<p><span class="LC_primary_menu_innertitle">'
                    613: 					. $title . '</span><span class="LC_primary_menu_innerarrow">&#9654;</span></p>';
                    614:                 $menu .= '<ul>';
                    615:                 $menu .= &build_submenu($target, $href, $translate);
                    616:                 $menu .= '</ul>';
                    617:                 $menu .= '</li>';    
                    618:             } else {    # href is the actual hyperlink and does not represent another submenu
                    619:                         # for the current menu title
                    620:                 if ($href =~ /(aboutme|rss\.html)$/) {
                    621:                     next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
                    622:                     $href =~ s/\[domain\]/$env{'user.domain'}/g;
                    623:                     $href =~ s/\[user\]/$env{'user.name'}/g;
                    624:                 }
                    625:                 unless (($href eq '') || ($href =~ /^\#/)) {
                    626:                     $target = ' target="_top"';
                    627:                 }
                    628: 
                    629:                 $menu .= '<li style="margin:0;padding:0;'. $bordertop . $borderbot .'">';
                    630:                 $menu .= '<a href="'.$href.'"'.$target.'>' .  $title . '</a>';
                    631:                 $menu .= '</li>';
1.425     raeburn   632:             }
1.375     raeburn   633:         }
                    634:     }
                    635:     return $menu;
                    636: }
                    637: 
1.40      www       638: sub innerregister {
1.468     raeburn   639:     my ($forcereg,$bread_crumbs,$group,$pagebuttonshide,$hostname) = @_;
1.152     albertel  640:     my $const_space = ($env{'request.state'} eq 'construct');
1.131     raeburn   641:     my $is_const_dir = 0;
1.120     raeburn   642: 
1.175     albertel  643:     if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; }
1.40      www       644: 
1.174     albertel  645:     $env{'request.registered'} = 1;
1.40      www       646: 
1.177     albertel  647:     undef(@inlineremote);
1.56      www       648: 
1.475   ! raeburn   649:     my ($mapurl,$resurl,$crstype,$navmap);
1.390     raeburn   650: 
1.393     raeburn   651:     if ($env{'request.course.id'}) {
1.443     raeburn   652: #
                    653: #course_type:  Course, Community, or Placement
                    654: #
                    655:         $crstype = &Apache::loncommon::course_type();
1.393     raeburn   656:         if ($env{'request.symb'}) {
                    657:             ($mapurl, my $rid, $resurl) = &Apache::lonnet::decode_symb(&Apache::lonnet::symbread());
                    658:             my $coursetitle = $env{'course.'.$env{'request.course.id'}.'.description'};
1.267     droeschl  659: 
1.393     raeburn   660:             my $maptitle = &Apache::lonnet::gettitle($mapurl);
                    661:             my $restitle = &Apache::lonnet::gettitle(&Apache::lonnet::symbread());
1.475   ! raeburn   662:             my (@crumbs,@mapcrumbs);
        !           663:             if (($env{'request.noversionuri'} ne '/adm/navmaps') && ($mapurl ne '')) {
        !           664:                 $navmap = Apache::lonnavmaps::navmap->new();
        !           665:                 if (ref($navmap)) {
        !           666:                     @mapcrumbs = $navmap->recursed_crumbs($mapurl);
        !           667:                 }
        !           668:             }
1.393     raeburn   669:             unless (($forcereg) &&
                    670:                     ($env{'request.noversionuri'} eq '/adm/navmaps') &&
1.443     raeburn   671:                     ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) ||
                    672:                     (($crstype eq 'Placement') && (!$env{'request.role.adv'}))) {
                    673:                 @crumbs = ({text  => $crstype.' Contents', 
1.393     raeburn   674:                             href  => "Javascript:gopost('/adm/navmaps','')"});
                    675:             }
                    676:             if ($mapurl ne $env{'course.'.$env{'request.course.id'}.'.url'}) { 
1.475   ! raeburn   677:                 if (@mapcrumbs) {
        !           678:                     push(@crumbs,@mapcrumbs);
        !           679:                 } else {
        !           680:                     push(@crumbs, {text  => '...',
        !           681:                                    no_mt => 1});
        !           682:                 }
1.393     raeburn   683:             }
                    684: 
1.475   ! raeburn   685:             unless ((($crstype eq 'Placement') && (!$env{'request.role.adv'})) || (@mapcrumbs) ||
        !           686:                     (!$maptitle) || ($maptitle eq 'default.sequence') ||
        !           687:                     ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'})) {
        !           688:                 push @crumbs, {text => $maptitle, no_mt => 1, href => $mapurl};
1.443     raeburn   689:             }
1.268     droeschl  690: 
1.393     raeburn   691:             push @crumbs, {text => $restitle, no_mt => 1} if $restitle; 
1.436     raeburn   692:             my @tools;
                    693:             if ($env{'request.filename'} =~ /\.page$/) {
                    694:                 my %breadcrumb_tools = &Apache::lonhtmlcommon::current_breadcrumb_tools();
                    695:                 if (ref($breadcrumb_tools{'tools'}) eq 'ARRAY') {
                    696:                     @tools = @{$breadcrumb_tools{'tools'}};
                    697:                 }
                    698:             }
1.393     raeburn   699:             &Apache::lonhtmlcommon::clear_breadcrumbs();
                    700:             &Apache::lonhtmlcommon::add_breadcrumb(@crumbs);
1.436     raeburn   701:             if (@tools) {
                    702:                 &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',@tools);
                    703:             }
1.393     raeburn   704:         } else {
                    705:             $resurl = $env{'request.noversionuri'};
                    706:             my $courseurl = &Apache::lonnet::courseid_to_courseurl($env{'request.course.id'});
                    707:             my $title = &mt('View Resource');
                    708:             if ($resurl =~ m{^\Q/uploaded$courseurl/supplemental/\E(default|\d+)/}) {
                    709:                 &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['folderpath','title']);
1.392     raeburn   710:                 &Apache::lonhtmlcommon::clear_breadcrumbs();
1.393     raeburn   711:                 if ($env{'form.title'}) {
                    712:                     $title = $env{'form.title'};
                    713:                 }
1.394     raeburn   714:                 my $trail;
1.393     raeburn   715:                 if ($env{'form.folderpath'}) {
1.468     raeburn   716:                     &prepare_functions($resurl,$forcereg,$group,undef,undef,1,$hostname);
1.394     raeburn   717:                     ($trail) =
1.393     raeburn   718:                         &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
                    719:                 } else {
                    720:                     &Apache::lonhtmlcommon::add_breadcrumb(
1.392     raeburn   721:                     {text  => "Supplemental $crstype Content",
                    722:                      href  => "javascript:gopost('/adm/supplemental','')"});
1.393     raeburn   723:                     $title = &mt('View Resource');
1.394     raeburn   724:                     ($trail) = 
                    725:                         &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
1.392     raeburn   726:                 }
1.394     raeburn   727:                 return $trail;
1.412     raeburn   728:             } elsif ($resurl =~ m{^\Q/uploaded$courseurl/portfolio/syllabus/}) {
                    729:                 &Apache::lonhtmlcommon::clear_breadcrumbs();
                    730:                 &prepare_functions('/public'.$courseurl."/syllabus",
1.468     raeburn   731:                                    $forcereg,$group,undef,undef,1,$hostname);
1.412     raeburn   732:                 $title = &mt('Syllabus File');
                    733:                 my ($trail) =
1.468     raeburn   734:                     &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,$hostname);
1.412     raeburn   735:                 return $trail;
1.392     raeburn   736:             }
1.395     raeburn   737:             unless ($env{'request.state'} eq 'construct') {
                    738:                 &Apache::lonhtmlcommon::clear_breadcrumbs();
                    739:                 &Apache::lonhtmlcommon::add_breadcrumb({text => 'View Resource'});
                    740:             }
1.392     raeburn   741:         }
1.390     raeburn   742:     } elsif (! $const_space){
1.328     droeschl  743:         #a situation when we're looking at a resource outside of context of a 
                    744:         #course or construction space (e.g. with cumulative rights)
                    745:         &Apache::lonhtmlcommon::clear_breadcrumbs();
1.390     raeburn   746:         unless ($env{'request.noversionuri'} =~ m{^/adm/$match_domain/$match_username/aboutme$}) {
                    747:             &Apache::lonhtmlcommon::add_breadcrumb({text => 'View Resource'});
                    748:         }
1.65      www       749:     }
1.41      www       750: # =============================================================================
                    751: # ============================ This is for URLs that actually can be registered
1.316     droeschl  752:     return '' unless ( ($env{'request.noversionuri'}!~m{^/(res/)*adm/}) 
                    753:                        || $forcereg );
1.390     raeburn   754:     my ($cdom,$cnum,%perms,$cfile,$switchserver,$home,$forceedit,
                    755:         $forceview,$editbutton);
1.391     raeburn   756:     if (($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) ||
                    757:         ($env{'request.role'} !~/^(aa|ca|au)/)) {
1.468     raeburn   758:         $editbutton = &prepare_functions($resurl,$forcereg,$group,'','','',$hostname);
1.390     raeburn   759:     }
                    760:     if ($editbutton eq '') {
1.399     raeburn   761:         $editbutton = &clear(6,1);
1.390     raeburn   762:     }
1.317     droeschl  763: 
1.390     raeburn   764: #
                    765: # This applies in course context
                    766: #
                    767:     if ($env{'request.course.id'}) {
                    768:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                    769:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    770:         $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
1.462     raeburn   771:         $perms{'cev'} = &Apache::lonnet::allowed('cev',$env{'request.course.id'});
1.390     raeburn   772:         my @privs;
                    773:         if ($env{'request.symb'} ne '') {
                    774:              if ($env{'request.filename'}=~/$LONCAPA::assess_re/) {
                    775:                  push(@privs,('mgr','vgr'));
                    776:              }
1.455     raeburn   777:              push(@privs,('opa','vpa'));
1.390     raeburn   778:         }
                    779:         foreach my $priv (@privs) {
                    780:             $perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});
                    781:             if (!$perms{$priv} && $env{'request.course.sec'} ne '') {
                    782:                 $perms{$priv} = 
                    783:                     &Apache::lonnet::allowed($priv,"$env{'request.course.id'}/$env{'request.course.sec'}");
                    784:             }
                    785:         }
                    786: #
                    787: # Determine whether or not to show Grades and Submissions buttons
                    788: #
                    789:         if ($env{'request.symb'} ne '' &&
                    790:             $env{'request.filename'}=~/$LONCAPA::assess_re/) {
                    791:             if ($perms{'mgr'}) {
                    792:                 &switch('','',7,2,'pgrd.png','Content Grades','grades[_4]',
                    793:                         "gocmd('/adm/grades','gradingmenu')",
                    794:                         'Content Grades');
                    795:             } elsif ($perms{'vgr'}) {
                    796:                 &switch('','',7,2,'subm.png','Content Submissions','missions[_1]',
                    797:                         "gocmd('/adm/grades','submission')",
                    798:                         'Content Submissions');
                    799:              }
                    800:         }
1.455     raeburn   801:         if (($env{'request.symb'} ne '') && (($perms{'opa'}) || ($perms{'vpa'}))) {
1.390     raeburn   802:             &switch('','',7,3,'pparm.png','Content Settings','parms[_2]',
                    803:                     "gocmd('/adm/parmset','set')",
                    804:                     'Content Settings');
1.107     albertel  805: 	}
1.393     raeburn   806: # End grades/submissions check
1.107     albertel  807: 
1.274     www       808: #
1.393     raeburn   809: # This applies to items inside a folder/page modifiable in the course.
1.274     www       810: #
1.462     raeburn   811:         if (($env{'request.symb'}=~/^uploaded/) && (($perms{'mdc'}) || ($perms{'cev'}))) {
1.393     raeburn   812:             my $text = 'Edit Folder';
1.395     raeburn   813:             if (($mapurl =~ /\.page$/) ||
                    814:                 ($env{'request.symb'}=~
1.396     raeburn   815:                      m{uploaded/$cdom/$cnum/default_\d+\.page$}))  {
1.393     raeburn   816:                 $text = 'Edit Page';
                    817:             }
                    818:             &switch('','',7,4,'docs-22x22.png',$text,'parms[_2]',
1.390     raeburn   819:                     "gocmd('/adm/coursedocs','direct')",
                    820:                     'Folder/Page Content');
1.258     raeburn   821:         }
1.390     raeburn   822: # End modifiable folder/page container check
                    823:     }
                    824: # End course context
                    825: 
1.41      www       826: # Prepare the rest of the buttons
1.383     raeburn   827:         my ($menuitems,$got_prt,$got_wishlist);
1.120     raeburn   828:         if ($const_space) {
1.274     www       829: #
                    830: # We are in construction space
                    831: #
1.353     www       832: 
1.355     raeburn   833:             my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
1.353     www       834: 	    my ($udom,$uname,$thisdisfn) =
1.355     raeburn   835: 		($env{'request.filename'}=~m{^\Q$londocroot/priv/\E([^/]+)/([^/]+)/(.*)$});
1.353     www       836:             my $currdir = '/priv/'.$udom.'/'.$uname.'/'.$thisdisfn;
1.131     raeburn   837:             if ($currdir =~ m-/$-) {
                    838:                 $is_const_dir = 1;
1.433     raeburn   839:                 if ($thisdisfn eq '') {
1.451     raeburn   840:                     unless (($env{'request.course.id'}) && 
                    841:                             ($env{'course.'.$env{'request.course.id'}.'.num'} eq $uname) &&
                    842:                             ($env{'course.'.$env{'request.course.id'}.'.domain'} eq $udom)) { 
                    843:                         $is_const_dir = 2;
                    844:                     }
1.433     raeburn   845:                 }
1.131     raeburn   846:             } else {
1.267     droeschl  847:                 $currdir =~ s|[^/]+$||;
1.200     foxr      848: 		my $cleandisfn = &Apache::loncommon::escape_single($thisdisfn);
1.208     albertel  849: 		my $esc_currdir = &Apache::loncommon::escape_single($currdir);
1.274     www       850: #
                    851: # Probably should be in mydesk.tab
                    852: #
1.131     raeburn   853:                 $menuitems=(<<ENDMENUITEMS);
1.344     www       854: s&6&1&list.png&Directory&dir[_1]&golist('$esc_currdir')&List current directory
1.353     www       855: s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/priv/$udom/$uname/$cleandisfn')&Retrieve old version
                    856: s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/priv/$udom/$uname/$cleandisfn')&Publish this resource
                    857: s&7&1&del.png&Delete&resource[_2]&gocstr('/adm/cfile?action=delete','/priv/$udom/$uname/$cleandisfn')&Delete this resource
                    858: s&7&2&prt.png&Print&printout[_1]&gocstr('/adm/printout','/priv/$udom/$uname/$cleandisfn')&Prepare a printable document
1.120     raeburn   859: ENDMENUITEMS
1.131     raeburn   860:             }
1.308     raeburn   861:                 if (ref($bread_crumbs) eq 'ARRAY') {
                    862:                     &Apache::lonhtmlcommon::clear_breadcrumbs();
                    863:                     foreach my $crumb (@{$bread_crumbs}){
                    864:                         &Apache::lonhtmlcommon::add_breadcrumb($crumb);
                    865:                     }
                    866:                 }
1.203     foxr      867:         } elsif ( defined($env{'request.course.id'}) && 
                    868: 		 $env{'request.symb'} ne '' ) {
1.274     www       869: #
1.383     raeburn   870: # We are in a course and looking at a registered URL
1.274     www       871: # Should probably be in mydesk.tab
                    872: #
1.443     raeburn   873:             $menuitems = "c&3&1";
                    874:             if (($crstype ne 'Placement') || ($env{'request.role.adv'})) {
                    875:                 $menuitems.="
1.444     raeburn   876: s&2&1&back.png&&&gopost('/adm/flip','back:'+currentURL)&Previous content resource&&1
                    877: s&2&3&forw.png&&&gopost('/adm/flip','forward:'+currentURL)&Next content resource&&3";
                    878:             } else {
                    879: # Suppress display of backward arrow for Placement Tests
                    880: # Suppress display of forward arrow for Placement Tests if this is the last resource.
                    881:                 my $showforw = 1;
                    882:                 if ($env{'request.symb'}) {
                    883:                     my $navmap = Apache::lonnavmaps::navmap->new();
                    884:                     if (ref($navmap)) {
                    885:                         if (&Apache::lonplacementtest::is_lastres($env{'request.symb'},$navmap)) {
                    886:                             $showforw = 0;
                    887:                         }
                    888:                     }
                    889:                 }
                    890:                 if ($showforw) {
                    891:                     $menuitems.="
                    892: s&2&3&forw.png&&&gopost('/adm/flip','forward:'+currentURL)&Next content resource&&3";
                    893:                 }
1.443     raeburn   894:             }
                    895: 	    $menuitems .= (<<ENDMENUITEMS);
                    896: 
1.77      www       897: c&6&3
                    898: c&8&1
                    899: c&8&2
1.344     www       900: s&8&3&prt.png&Print&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
1.41      www       901: ENDMENUITEMS
1.383     raeburn   902:             $got_prt = 1;
                    903:             if (($env{'user.adv'}) && ($env{'request.uri'} =~ /^\/res/)
                    904:                 && (!$env{'request.enc'})) {
1.452     raeburn   905:                 my ($cnum,$cdom) = &Apache::loncommon::crsauthor_url($env{'request.uri'});
                    906:                 unless ($cnum) {
                    907:                     # wishlist is only available for users with access to resource-pool
                    908:                     # and links can only be set for resources within the resource-pool
                    909:                     $menuitems .= (<<ENDMENUITEMS);
1.431     golterma  910: s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in my personal Stored Links repository&&1
1.332     wenzelju  911: ENDMENUITEMS
1.452     raeburn   912:                     $got_wishlist = 1;
                    913:                 }
1.332     wenzelju  914:             }
1.216     albertel  915: 
1.243     tempelho  916: my $currentURL = &Apache::loncommon::get_symb();
                    917: my ($symb_old,$symb_old_enc) = &Apache::loncommon::clean_symb($currentURL);
                    918: my $annotation = &Apache::loncommon::get_annotation($symb_old,$symb_old_enc);
                    919: $menuitems.="s&9&3&";
                    920: if(length($annotation) > 0){
1.317     droeschl  921: 	$menuitems.="anot2.png";
1.243     tempelho  922: }else{
1.317     droeschl  923: 	$menuitems.="anot.png";
1.243     tempelho  924: }
1.344     www       925: $menuitems.="&Notes&&annotate()&";
1.243     tempelho  926: $menuitems.="Make notes and annotations about this resource&&1\n";
1.428     raeburn   927: my $is_mobile;
                    928: if ($env{'browser.mobile'}) {
                    929:     $is_mobile = 1;
                    930: }
1.243     tempelho  931: 
1.472     raeburn   932:             unless ($env{'request.noversionuri'}=~/\/(bulletinboard|smppg|navmaps|syllabus|aboutme|viewclasslist|portfolio|ext\.tool)(\?|$)/) {
1.382     raeburn   933: 		if ((!$env{'request.enc'}) && ($env{'request.noversionuri'} !~ m{^/adm/wrapper/ext/}) && ($env{'request.noversionuri'} !~ m{^/uploaded/$match_domain/$match_courseid/docs/})) {
1.216     albertel  934: 		    $menuitems.=(<<ENDREALRES);
1.428     raeburn   935: s&6&3&catalog.png&Info&info[_1]&catalog_info('$is_mobile')&Show Metadata
1.216     albertel  936: ENDREALRES
                    937:                 }
1.422     raeburn   938:                 unless (($env{'request.noversionuri'} =~ m{^/uploaded/$match_domain/$match_courseid/docs/}) ||
                    939:                         ($env{'request.noversionuri'} =~ m{^\Q/adm/wrapper/\E(ext|uploaded)/})) {  
1.382     raeburn   940:                     $menuitems.=(<<ENDREALRES);
1.344     www       941: s&8&1&eval.png&Evaluate&this[_1]&gopost('/adm/evaluate',currentURL,1)&Provide my evaluation of this resource
1.382     raeburn   942: ENDREALRES
                    943:                 }
1.422     raeburn   944:                 unless ($env{'request.noversionuri'} =~ m{^\Q/adm/wrapper/\E(ext|uploaded)/}) {
                    945:                     $menuitems.=(<<ENDREALRES);
1.344     www       946: s&8&2&fdbk.png&Communicate&discuss[_1]&gopost('/adm/feedback',currentURL,1)&Provide feedback messages or contribute to the course discussion about this resource
1.77      www       947: ENDREALRES
1.422     raeburn   948:                 }
1.120     raeburn   949: 	    }
                    950:         }
1.203     foxr      951: 	if ($env{'request.uri'} =~ /^\/res/) {
1.383     raeburn   952:             unless ($got_prt) {
                    953: 	        $menuitems .= (<<ENDMENUITEMS);
1.344     www       954: s&8&3&prt.png&Print&printout[_1]&gopost('/adm/printout',currentURL)&Prepare a printable document
1.203     foxr      955: ENDMENUITEMS
1.384     raeburn   956:                 $got_prt = 1;
1.383     raeburn   957:             }
                    958:             unless ($got_wishlist) {
                    959:                 if (($env{'user.adv'}) && (!$env{'request.enc'})) {
                    960:                     # wishlist is only available for users with access to resource-pool
                    961:                     $menuitems .= (<<ENDMENUITEMS);
1.431     golterma  962: 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
1.332     wenzelju  963: ENDMENUITEMS
1.383     raeburn   964:                     $got_wishlist = 1;
                    965:                 }
                    966: 	    }
                    967:         }
1.41      www       968:         my $buttons='';
                    969:         foreach (split(/\n/,$menuitems)) {
                    970: 	    my ($command,@rest)=split(/\&/,$_);
1.220     raeburn   971:             my $idx=10*$rest[0]+$rest[1];
                    972:             if (&hidden_button_check() eq 'yes') {
                    973:                 if ($idx == 21 ||$idx == 23) {
                    974:                     $buttons.=&switch('','',@rest);
                    975:                 } else {
                    976:                     $buttons.=&clear(@rest);
                    977:                 }
                    978:             } else {  
                    979:                 if ($command eq 's') {
                    980: 	            $buttons.=&switch('','',@rest);
                    981:                 } else {
                    982:                     $buttons.=&clear(@rest);
                    983:                 }
1.41      www       984:             }
                    985:         }
1.445     raeburn   986:         my $showprogress;
                    987:         if (($crstype eq 'Placement') && (!$env{'request.role.adv'})) {
                    988:             $showprogress = &placement_progress();
                    989:         }
                    990: 
                    991: 	my $addremote=0;
                    992: 	foreach (@inlineremote) { if ($_ ne '') { $addremote=1; last;} }
1.148     albertel  993: 
1.301     droeschl  994:     if ($addremote) {
1.458     raeburn   995:         my ($countdown,$buttonshide);
1.436     raeburn   996:         if ($env{'request.filename'} =~ /\.page$/) {
                    997:             my %breadcrumb_tools = &Apache::lonhtmlcommon::current_breadcrumb_tools();
                    998:             if (ref($breadcrumb_tools{'tools'}) eq 'ARRAY') {
1.458     raeburn   999:                 $countdown = $breadcrumb_tools{'tools'}->[0];
1.436     raeburn  1000:             }
1.458     raeburn  1001:             $buttonshide = $pagebuttonshide;
1.436     raeburn  1002:         } else {
                   1003:             $countdown = &countdown_timer();
1.458     raeburn  1004:             $buttonshide = &hidden_button_check();
1.436     raeburn  1005:         }
1.342     www      1006:         &Apache::lonhtmlcommon::clear_breadcrumb_tools();
1.301     droeschl 1007: 
1.342     www      1008:             &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.312     droeschl 1009:                 'navigation', @inlineremote[21,23]);
                   1010: 
1.458     raeburn  1011:         if ($buttonshide eq 'yes') {
1.378     raeburn  1012:             if ($countdown) {
                   1013:                 &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$countdown);
                   1014:             }
1.445     raeburn  1015:             if ($showprogress) {
                   1016:                 &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$showprogress);
                   1017:             }
1.378     raeburn  1018:         } else {
                   1019:             my @tools = @inlineremote[93,91,81,82,83];
                   1020:             if ($countdown) {
                   1021:                 unshift(@tools,$countdown);
                   1022:             }
1.342     www      1023:             &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.378     raeburn  1024:                 'tools',@tools);
1.313     droeschl 1025: 
                   1026:             #publish button in construction space
                   1027:             if ($env{'request.state'} eq 'construct'){
1.342     www      1028:                 &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.349     raeburn  1029:                      'advtools', $inlineremote[63]);
1.342     www      1030:             } else {
                   1031:                 &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.349     raeburn  1032:                      'tools', $inlineremote[63]);
1.313     droeschl 1033:             }
1.390     raeburn  1034:             &advtools_crumbs(@inlineremote);
1.301     droeschl 1035:         }
1.445     raeburn  1036:     } else {
                   1037:         if ($showprogress) {
                   1038:             &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$showprogress);
                   1039:         }
1.38      www      1040:     }
1.433     raeburn  1041:     my ($topic_help,$topic_help_text);
                   1042:     if ($is_const_dir == 2) {
1.434     raeburn  1043:         if ((($ENV{'SERVER_PORT'} == 443) || 
                   1044:              ($Apache::lonnet::protocol{$Apache::lonnet::perlvar{'lonHostID'}} eq 'https')) && 
                   1045:             (&Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'},'webdav'))) {
1.433     raeburn  1046:             $topic_help = 'Authoring_WebDAV,Authoring_WebDAV_Mac_10v6,Authoring_WebDAV_Mac_10v10,'.
                   1047:                           'Authoring_WebDAV_Windows_v7,Authoring_WebDAV_Linux_Centos';
                   1048:             $topic_help_text = 'About WebDAV access';
                   1049:         }
                   1050:     }
1.342     www      1051:     return   &Apache::lonhtmlcommon::scripttag('', 'start')
1.433     raeburn  1052:            . &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0,'','','','',$topic_help,$topic_help_text)
1.342     www      1053:            . &Apache::lonhtmlcommon::scripttag('', 'end');
1.38      www      1054: }
                   1055: 
1.389     raeburn  1056: sub get_editbutton {
1.468     raeburn  1057:     my ($cfile,$home,$switchserver,$forceedit,$forceview,$forcereg,$hostname) = @_;
1.398     raeburn  1058:     my $jscall;
                   1059:     if (($forceview) && ($env{'form.todocs'})) {
1.463     raeburn  1060:         my ($folderpath,$command,$navmap);
1.398     raeburn  1061:         if ($env{'request.symb'}) {
1.463     raeburn  1062:             $folderpath = &Apache::loncommon::symb_to_docspath($env{'request.symb'},\$navmap);
1.398     raeburn  1063:         } elsif ($env{'form.folderpath'} =~ /^supplemental/) {
                   1064:             $folderpath = $env{'form.folderpath'};
                   1065:             $command = '&forcesupplement=1';
                   1066:         }
                   1067:         $folderpath = &escape(&HTML::Entities::encode(&escape($folderpath),'<>&"'));
                   1068:         $jscall = "go('/adm/coursedocs?folderpath=$folderpath$command')";
                   1069:     } else {
1.459     raeburn  1070:         my $suppanchor;
                   1071:         if ($env{'form.folderpath'}) {
                   1072:             $suppanchor = $env{'form.anchor'};
                   1073:         }
1.398     raeburn  1074:         $jscall = &Apache::lonhtmlcommon::jump_to_editres($cfile,$home,$switchserver,
1.393     raeburn  1075:                                                 $forceedit,$forcereg,$env{'request.symb'},
                   1076:                                                 &escape($env{'form.folderpath'}),
1.468     raeburn  1077:                                                 &escape($env{'form.title'}),$hostname,
                   1078:                                                 $env{'form.idx'},&escape($env{'form.suppurl'}),
                   1079:                                                 $env{'form.todocs'},$suppanchor);
1.398     raeburn  1080:     }
1.389     raeburn  1081:     if ($jscall) {
1.390     raeburn  1082:         my $icon = 'pcstr.png';
                   1083:         my $label = 'Edit';
                   1084:         if ($forceview) {
                   1085:             $icon = 'tolastloc.png';
                   1086:             $label = 'Exit Editing';
                   1087:         }
                   1088:         &switch('','',6,1,$icon,$label,'resource[_2]',
                   1089:                 $jscall,"Edit this resource");
                   1090:         return 1;
                   1091:     }
                   1092:     return;
                   1093: }
                   1094: 
                   1095: sub prepare_functions {
1.468     raeburn  1096:     my ($resurl,$forcereg,$group,$bread_crumbs,$advtools,$docscrumbs,$hostname) = @_;
1.390     raeburn  1097:     unless ($env{'request.registered'}) {
                   1098:         undef(@inlineremote);
                   1099:     }
                   1100:     my ($cdom,$cnum,%perms,$cfile,$switchserver,$home,$forceedit,
                   1101:         $forceview);
                   1102: 
                   1103:     if ($env{'request.course.id'}) {
                   1104:         $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                   1105:         $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                   1106:         $perms{'mdc'} = &Apache::lonnet::allowed('mdc',$env{'request.course.id'});
                   1107:     }
                   1108: 
                   1109:     my $editbutton = '';
                   1110: #
                   1111: # Determine whether or not to display 'Edit' icon/button
                   1112: #
                   1113:     if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) {
                   1114:         my $file=&Apache::lonnet::declutter($env{'request.filename'});
1.391     raeburn  1115:         ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1116:             &Apache::lonnet::can_edit_resource($file,$cnum,$cdom,
                   1117:                 &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group);
                   1118:         if (($cfile) && ($home ne '') && ($home ne 'no_host')) {
                   1119:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
1.390     raeburn  1120:                                           $forceedit,$forceview,$forcereg);
                   1121:         }
1.391     raeburn  1122:     } elsif ((!$env{'request.course.id'}) &&
1.390     raeburn  1123:              ($env{'user.author'}) && ($env{'request.filename'}) &&
                   1124:              ($env{'request.role'} !~/^(aa|ca|au)/)) {
                   1125: #
                   1126: # Currently do not have the role of author or co-author.
                   1127: # Do we have authoring privileges for the resource?
                   1128: #
                   1129:         my $file=&Apache::lonnet::declutter($env{'request.filename'});
                   1130:         ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1131:             &Apache::lonnet::can_edit_resource($file,$cnum,$cdom,
                   1132:                 &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group);
                   1133:         if (($cfile) && ($home ne '') && ($home ne 'no_host')) {
                   1134:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1135:                                           $forceedit,$forceview,$forcereg);
                   1136:         }
                   1137:     } elsif ($env{'request.course.id'}) {
                   1138: #
                   1139: # This applies in course context
                   1140: #
1.412     raeburn  1141:         if (($perms{'mdc'}) &&
1.469     raeburn  1142:             (($resurl =~ m{^/?public/$cdom/$cnum/syllabus}) ||
                   1143:             ($resurl =~ m{^/?uploaded/$cdom/$cnum/portfolio/syllabus/}))) {
1.470     raeburn  1144:             if ($resurl =~ m{^/}) {
                   1145:                 $cfile = $resurl;
                   1146:             } else {
                   1147:                 $cfile = "/$resurl";
                   1148:             }
1.411     raeburn  1149:             $home = &Apache::lonnet::homeserver($cnum,$cdom);
                   1150:             if ($env{'form.forceedit'}) {
                   1151:                 $forceview = 1;
1.390     raeburn  1152:             } else {
1.411     raeburn  1153:                 $forceedit = 1;
1.390     raeburn  1154:             }
1.411     raeburn  1155:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
1.468     raeburn  1156:                                           $forceedit,$forceview,$forcereg,
                   1157:                                           $hostname);
1.393     raeburn  1158:         } elsif (($resurl eq '/adm/extresedit') &&
                   1159:                  (($env{'form.symb'}) || ($env{'form.folderpath'}))) {
                   1160:             ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1161:             &Apache::lonnet::can_edit_resource($resurl,$cnum,$cdom,$resurl,
                   1162:                                                $env{'form.symb'});
                   1163:             if ($cfile ne '') {
                   1164:                 $editbutton = &get_editbutton($cfile,$home,$switchserver,
1.468     raeburn  1165:                                               $forceedit,$forceview,$forcereg);
1.393     raeburn  1166:             }
1.406     raeburn  1167:         } elsif (($resurl =~ m{^/?adm/viewclasslist$}) &&
                   1168:                  (&Apache::lonnet::allowed('opa',$env{'request.course.id'}))) {
                   1169:             ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1170:             &Apache::lonnet::can_edit_resource($resurl,$cnum,$cdom,$resurl,
                   1171:                                                $env{'form.symb'});
                   1172:             $editbutton = &get_editbutton($cfile,$home,$switchserver,
                   1173:                                           $forceedit,$forceview,$forcereg);
1.405     raeburn  1174:         } elsif (($resurl !~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) &&
                   1175:                  ($resurl ne '/cgi-bin/printout.pl')) {
1.390     raeburn  1176:             if ($env{'request.filename'}) {
                   1177:                 my $file=&Apache::lonnet::declutter($env{'request.filename'});
                   1178:                 ($cfile,$home,$switchserver,$forceedit,$forceview) =
                   1179:                     &Apache::lonnet::can_edit_resource($file,$cnum,$cdom,
                   1180:                         &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group);
                   1181:                 if ($cfile ne '') {
                   1182:                     $editbutton = &get_editbutton($cfile,$home,$switchserver,
1.468     raeburn  1183:                                                   $forceedit,$forceview,$forcereg,
                   1184:                                                   $hostname);
1.390     raeburn  1185:                 }
                   1186:             }
                   1187:         }
                   1188:     }
                   1189: # End determination of 'Edit' icon/button display
                   1190: 
1.393     raeburn  1191:     if ($env{'request.course.id'}) {
1.390     raeburn  1192: # This applies to about me page for users in a course
1.391     raeburn  1193:         if ($resurl =~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) {
1.390     raeburn  1194:             my ($sdom,$sname) = ($1,$2);
                   1195:             unless (&Apache::lonnet::is_course($sdom,$sname)) {
                   1196:                 &switch('','',6,4,'mail-message-new-22x22.png','Message to user',
                   1197:                         '',
1.415     raeburn  1198:                         "go('/adm/email?compose=individual&amp;recname=$sname&amp;recdom=$sdom')",
1.390     raeburn  1199:                             'Send message to specific user');
                   1200:             }
1.391     raeburn  1201:             my $hideprivileged = 1;
                   1202:             if (&Apache::lonnet::in_course($sdom,$sname,$cdom,$cnum,undef,
                   1203:                                            $hideprivileged)) {
1.390     raeburn  1204:                 foreach my $priv ('vsa','vgr','srm') {
                   1205:                     $perms{$priv} = &Apache::lonnet::allowed($priv,$env{'request.course.id'});
                   1206:                     if (!$perms{$priv} && $env{'request.course.sec'} ne '') {
                   1207:                         $perms{$priv} =
                   1208:                             &Apache::lonnet::allowed($priv,"$env{'request.course.id'}/$env{'request.course.sec'}");
                   1209:                     }
                   1210:                 }
                   1211:                 if ($perms{'vsa'}) {
                   1212:                     &switch('','',6,5,'trck-22x22.png','Activity',
                   1213:                             '',
                   1214:                             "go('/adm/trackstudent?selected_student=$sname:$sdom')",
                   1215:                             'View recent activity by this person');
                   1216:                 }
                   1217:                 if ($perms{'vgr'}) {
                   1218:                     &switch('','',6,6,'rsrv-22x22.png','Reservations',
                   1219:                             '',
1.415     raeburn  1220:                             "go('/adm/slotrequest?command=showresv&amp;origin=aboutme&amp;uname=$sname&amp;udom=$sdom')",
1.390     raeburn  1221:                             'Slot reservation history');
                   1222:                 }
                   1223:                 if ($perms{'srm'}) {
                   1224:                     &switch('','',6,7,'contact-new-22x22.png','Records',
                   1225:                             '',
1.415     raeburn  1226:                             "go('/adm/email?recordftf=retrieve&amp;recname=$sname&amp;recdom=$sdom')",
1.390     raeburn  1227:                             'Add records');
                   1228:                 }
                   1229:             }
1.393     raeburn  1230:         }
                   1231:         if (($env{'form.folderpath'} =~ /^supplemental/) &&
                   1232:             (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) &&
                   1233:             (($resurl =~ m{^/adm/wrapper/ext/}) ||
1.472     raeburn  1234:              ($resurl =~ m{^/adm/$cdom/$cnum/\d+/ext\.tool$}) ||
1.393     raeburn  1235:              ($resurl =~ m{^/uploaded/$cdom/$cnum/supplemental/}) ||
1.397     raeburn  1236:              ($resurl eq '/adm/supplemental') ||
                   1237:              ($resurl =~ m{^/public/$cdom/$cnum/syllabus$}) ||
                   1238:              ($resurl =~ m{^/adm/$match_domain/$match_username/aboutme$}))) {
1.393     raeburn  1239:             my @folders=split('&',$env{'form.folderpath'});
1.394     raeburn  1240:             if ((@folders > 2) || ($resurl ne '/adm/supplemental')) {
1.459     raeburn  1241:                 my $suppanchor;
                   1242:                 if ($resurl =~ m{^/adm/wrapper/ext/}) {
                   1243:                     $suppanchor = $env{'form.anchor'};
                   1244:                 }
1.393     raeburn  1245:                 my $esc_path=&escape(&HTML::Entities::encode(&escape($env{'form.folderpath'}),'<>&"'));
1.468     raeburn  1246:                 my $link = '/adm/coursedocs?command=direct&amp;forcesupplement=1&amp;supppath='.
                   1247:                            "$esc_path&amp;anchor=$suppanchor";
                   1248:                 if ($env{'request.use_absolute'} ne '') {
                   1249:                     $link = $env{'request.use_absolute'}.$link;
                   1250:                 }
1.393     raeburn  1251:                 &switch('','',7,4,'docs-22x22.png','Edit Folder','parms[_2]',
1.468     raeburn  1252:                         "location.href='$link'",'Folder/Page Content');
1.393     raeburn  1253:             }
1.390     raeburn  1254:         }
                   1255:     }
                   1256: 
                   1257: # End checking for items for about me page for users in a course
1.393     raeburn  1258:     if ($docscrumbs) {
                   1259:         &Apache::lonhtmlcommon::clear_breadcrumb_tools();
                   1260:         &advtools_crumbs(@inlineremote);
                   1261:         return $editbutton;
                   1262:     } elsif ($env{'request.registered'}) {
1.390     raeburn  1263:         return $editbutton;
                   1264:     } else {
                   1265:         if (ref($bread_crumbs) eq 'ARRAY') {
                   1266:             if (@inlineremote > 0) {
                   1267:                 if (ref($advtools) eq 'ARRAY') {
                   1268:                     @{$advtools} = @inlineremote;
                   1269:                 }
                   1270:             }
                   1271:             return;
                   1272:         } elsif (@inlineremote > 0) {
                   1273:             &Apache::lonhtmlcommon::clear_breadcrumb_tools();
                   1274:             &advtools_crumbs(@inlineremote);
                   1275:             return   &Apache::lonhtmlcommon::scripttag('', 'start')
                   1276:                    . &Apache::lonhtmlcommon::breadcrumbs(undef,undef,0)
                   1277:                    . &Apache::lonhtmlcommon::scripttag('', 'end');
                   1278:         }
                   1279:     }
                   1280: }
                   1281: 
                   1282: sub advtools_crumbs {
                   1283:     my @funcs = @_;
                   1284:     if ($env{'request.noversionuri'} =~ m{^/adm/$match_domain/$match_username/aboutme$}) {
                   1285:         &Apache::lonhtmlcommon::add_breadcrumb_tool(
                   1286:             'advtools', @funcs[61,64,65,66,67,74]);
                   1287:     } elsif ($env{'request.noversionuri'} !~ m{^/adm/(navmaps|viewclasslist)(\?|$)}) {
                   1288:         &Apache::lonhtmlcommon::add_breadcrumb_tool(
                   1289:             'advtools', @funcs[61,71,72,73,74,92]);
1.393     raeburn  1290:     } elsif ($env{'request.noversionuri'} eq '/adm/viewclasslist') {
                   1291:         &Apache::lonhtmlcommon::add_breadcrumb_tool(
1.407     raeburn  1292:             'advtools', $funcs[61]);
1.393     raeburn  1293:     }
1.412     raeburn  1294:     return;
1.258     raeburn  1295: }
                   1296: 
1.2       www      1297: # ================================================================== Raw Config
                   1298: 
1.3       www      1299: sub clear {
                   1300:     my ($row,$col)=@_;
1.316     droeschl 1301:     $inlineremote[10*$row+$col]='';
                   1302:     return ''; 
1.3       www      1303: }
                   1304: 
1.40      www      1305: # ============================================ Switch a button or create a link
1.25      matthew  1306: # Switch acts on the javascript that is executed when a button is clicked.  
                   1307: # The javascript is usually similar to "go('/adm/roles')" or "cstrgo(..)".
1.40      www      1308: 
1.2       www      1309: sub switch {
1.209     www      1310:     my ($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat,$nobreak)=@_;
1.2       www      1311:     $act=~s/\$uname/$uname/g;
                   1312:     $act=~s/\$udom/$udom/g;
1.88      www      1313:     $top=&mt($top);
                   1314:     $bot=&mt($bot);
                   1315:     $desc=&mt($desc);
1.209     www      1316:     my $idx=10*$row+$col;
                   1317:     $category_members{$cat}.=':'.$idx;
                   1318: 
1.320     droeschl 1319: # Inline Menu
1.317     droeschl 1320:     if ($nobreak==2) { return ''; }
                   1321:     my $text=$top.' '.$bot;
                   1322:     $text=~s/\s*\-\s*//gs;
1.105     www      1323: 
1.317     droeschl 1324:     my $pic=
1.225     albertel 1325: 	   '<img alt="'.$text.'" src="'.
                   1326: 	   &Apache::loncommon::lonhttpdurl('/res/adm/pages/'.$img).
1.303     droeschl 1327: 	   '" align="'.($nobreak==3?'right':'left').'" class="LC_icon" />';
1.317     droeschl 1328:     if ($env{'browser.interface'} eq 'faketextual') {
1.274     www      1329: # Main Menu
1.103     www      1330: 	   if ($nobreak==3) {
1.209     www      1331: 	       $inlineremote[$idx]="\n".
1.177     albertel 1332: 		   '<td class="LC_menubuttons_text" align="right">'.$text.
1.247     harmsja  1333: 		   '</td><td align="left">'.
1.103     www      1334: 		   '<a href="javascript:'.$act.';">'.$pic.'</a></td></tr>';
                   1335: 	   } elsif ($nobreak) {
1.209     www      1336: 	       $inlineremote[$idx]="\n<tr>".
1.247     harmsja  1337: 		   '<td align="left">'.
1.177     albertel 1338: 		   '<a href="javascript:'.$act.';">'.$pic.'</a></td>
1.215     www      1339:                     <td class="LC_menubuttons_text" align="left"><a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$text.'</span></a></td>';
1.103     www      1340: 	   } else {
1.209     www      1341: 	       $inlineremote[$idx]="\n<tr>".
1.247     harmsja  1342: 		   '<td align="left">'.
1.103     www      1343: 		   '<a href="javascript:'.$act.';">'.$pic.
1.177     albertel 1344: 		   '</a></td><td class="LC_menubuttons_text" colspan="3">'.
1.215     www      1345: 		   '<a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$desc.'</span></a></td></tr>';
1.103     www      1346: 	   }
1.317     droeschl 1347:     } else {
1.103     www      1348: # Inline Menu
1.378     raeburn  1349:         my @tools = (93,91,81,82,83);
                   1350:         unless ($env{'request.state'} eq 'construct') {
                   1351:             push(@tools,63);
                   1352:         }
                   1353:         if (($env{'environment.icons'} eq 'iconsonly') && 
                   1354:             (grep(/^$idx$/,@tools))) {
                   1355:             $inlineremote[$idx] =
                   1356:         '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.'</a>';
                   1357:         } else {
                   1358:             $inlineremote[$idx] =
1.317     droeschl 1359:        '<a title="'.$desc.'" class="LC_menubuttons_link" href="javascript:'.$act.';">'.$pic.
1.344     www      1360:        '<span class="LC_menubuttons_inline_text">'.$top.'&nbsp;</span></a>';
1.378     raeburn  1361:         }
1.317     droeschl 1362:     }
1.56      www      1363:     return '';
1.2       www      1364: }
                   1365: 
                   1366: sub secondlevel {
                   1367:     my $output='';
                   1368:     my 
1.209     www      1369:     ($uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat)=@_;
1.2       www      1370:     if ($prt eq 'any') {
1.209     www      1371: 	   $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1372:     } elsif ($prt=~/^r(\w+)/) {
                   1373:         if ($rol eq $1) {
1.209     www      1374:            $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1375:         }
                   1376:     }
                   1377:     return $output;
                   1378: }
                   1379: 
1.56      www      1380: sub inlinemenu {
1.210     albertel 1381:     undef(@inlineremote);
                   1382:     undef(%category_members);
1.275     www      1383: # calling rawconfig with "1" will evaluate mydesk.tab, even if there is no active remote control
1.56      www      1384:     &rawconfig(1);
1.309     bisitz   1385:     my $output='<table><tr>';
1.209     www      1386:     for (my $col=1; $col<=2; $col++) {
1.241     riegler  1387:         $output.='<td class="LC_mainmenu_col_fieldset">';
1.209     www      1388:         for (my $row=1; $row<=8; $row++) {
                   1389:             foreach my $cat (keys(%category_members)) {
                   1390:                if ($category_positions{$cat} ne "$col,$row") { next; }
1.247     harmsja  1391:                #$output.='<table><tr><td colspan="4" class="LC_menubuttons_category">'.&mt($category_names{$cat}).'</td></tr>';
1.309     bisitz   1392:                $output.='<div class="LC_Box LC_400Box">';
                   1393: 	       $output.='<h3 class="LC_hcell">'.&mt($category_names{$cat}).'</h3>';
1.247     harmsja  1394:                $output.='<table>';
1.240     riegler  1395:                my %active=();
                   1396:                foreach my $menu_item (split(/\:/,$category_members{$cat})) {
                   1397:                   if ($inlineremote[$menu_item]) {
                   1398:                      $active{$menu_item}=1;
                   1399:                   }
                   1400:                }  
                   1401:                foreach my $item (sort(keys(%active))) {
                   1402:                   $output.=$inlineremote[$item];
                   1403:                }
                   1404:                $output.='</table>';
1.245     harmsja  1405:                $output.='</div>';
1.240     riegler  1406:             }
                   1407:          }
                   1408:          $output.="</td>";
                   1409:     }
                   1410:     $output.="</tr></table>";
                   1411:     return $output;
                   1412: }
                   1413: 
1.2       www      1414: sub rawconfig {
1.274     www      1415: #
                   1416: # This evaluates mydesk.tab
                   1417: # Need to add more positions and more privileges to deal with all
                   1418: # menu items.
                   1419: #
1.34      www      1420:     my $textualoverride=shift;
                   1421:     my $output='';
1.316     droeschl 1422:     return '' unless $textualoverride;
1.152     albertel 1423:     my $uname=$env{'user.name'};
                   1424:     my $udom=$env{'user.domain'};
                   1425:     my $adv=$env{'user.adv'};
1.266     raeburn  1426:     my $show_course=&Apache::loncommon::show_course();
1.152     albertel 1427:     my $author=$env{'user.author'};
1.5       www      1428:     my $crs='';
1.295     raeburn  1429:     my $crstype='';
1.152     albertel 1430:     if ($env{'request.course.id'}) {
                   1431:        $crs='/'.$env{'request.course.id'};
                   1432:        if ($env{'request.course.sec'}) {
                   1433: 	   $crs.='_'.$env{'request.course.sec'};
1.7       www      1434:        }
1.8       www      1435:        $crs=~s/\_/\//g;
1.295     raeburn  1436:        $crstype = &Apache::loncommon::course_type();
1.5       www      1437:     }
1.152     albertel 1438:     my $pub=($env{'request.state'} eq 'published');
                   1439:     my $con=($env{'request.state'} eq 'construct');
                   1440:     my $rol=$env{'request.role'};
1.427     raeburn  1441:     my $requested_domain;
                   1442:     if ($rol) {
                   1443:        $requested_domain = $env{'request.role.domain'};
                   1444:     }
1.184     raeburn  1445:     foreach my $line (@desklines) {
1.209     www      1446:         my ($row,$col,$pro,$prt,$img,$top,$bot,$act,$desc,$cat)=split(/\:/,$line);
1.3       www      1447:         $prt=~s/\$uname/$uname/g;
                   1448:         $prt=~s/\$udom/$udom/g;
1.295     raeburn  1449:         if ($prt =~ /\$crs/) {
                   1450:             next unless ($env{'request.course.id'});
                   1451:             next if ($crstype eq 'Community');
                   1452:             $prt=~s/\$crs/$crs/g;
                   1453:         } elsif ($prt =~ /\$cmty/) {
                   1454:             next unless ($env{'request.course.id'});
                   1455:             next if ($crstype ne 'Community');
                   1456:             $prt=~s/\$cmty/$crs/g;
                   1457:         }
1.427     raeburn  1458:         if ($prt =~ m/\$requested_domain/) {
                   1459:             if ((!$requested_domain) && ($pro eq 'pbre') && ($env{'user.adv'})) {
                   1460:                 $prt=~s/\$requested_domain/$env{'user.domain'}/g;
                   1461:             } else {
                   1462:                 $prt=~s/\$requested_domain/$requested_domain/g;
                   1463:             }
                   1464:         }
1.211     www      1465:         if ($category_names{$cat}!~/\w/) { $cat='oth'; }
1.3       www      1466:         if ($pro eq 'clear') {
1.4       www      1467: 	    $output.=&clear($row,$col);
1.3       www      1468:         } elsif ($pro eq 'any') {
1.2       www      1469:                $output.=&secondlevel(
1.209     www      1470: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1471: 	} elsif ($pro eq 'smp') {
                   1472:             unless ($adv) {
                   1473:                $output.=&secondlevel(
1.209     www      1474:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1475:             }
                   1476:         } elsif ($pro eq 'adv') {
                   1477:             if ($adv) {
                   1478:                $output.=&secondlevel(
1.209     www      1479: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1480:             }
1.231     albertel 1481: 	} elsif ($pro eq 'shc') {
                   1482:             if ($show_course) {
                   1483:                $output.=&secondlevel(
                   1484:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
                   1485:             }
                   1486:         } elsif ($pro eq 'nsc') {
                   1487:             if (!$show_course) {
                   1488:                $output.=&secondlevel(
                   1489: 	  $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
                   1490:             }
1.81      matthew  1491:         } elsif (($pro=~/^p(\w+)/) && ($prt)) {
1.295     raeburn  1492:             my $priv = $1;
                   1493:             if ($priv =~ /^mdc(Course|Community)/) {
                   1494:                 if ($crstype eq $1) {
                   1495:                     $priv = 'mdc';
                   1496:                 } else {
                   1497:                     next;
                   1498:                 }
                   1499:             }
1.427     raeburn  1500:             if ((($priv eq 'bre') && (&Apache::lonnet::allowed($priv,$prt) eq 'F')) ||
                   1501:                 (($priv ne 'bre') && (&Apache::lonnet::allowed($priv,$prt)))) {
                   1502:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.4       www      1503:             }
1.295     raeburn  1504:         } elsif ($pro eq 'course')  {
                   1505:             if (($env{'request.course.fn'}) && ($crstype ne 'Community')) {
1.209     www      1506:                $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.81      matthew  1507: 	    }
1.295     raeburn  1508:         } elsif ($pro eq 'community')  {
                   1509:             if (($env{'request.course.fn'}) && ($crstype eq 'Community')) {
                   1510:                $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1511:             }
1.124     matthew  1512:         } elsif ($pro =~ /^courseenv_(.*)$/) {
                   1513:             my $key = $1;
1.307     raeburn  1514:             if ($crstype ne 'Community') {
                   1515:                 my $coursepref = $env{'course.'.$env{'request.course.id'}.'.'.$key};
                   1516:                 if ($key eq 'canuse_pdfforms') {
                   1517:                     if ($env{'request.course.id'} && $coursepref eq '') {
                   1518:                         my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
                   1519:                         $coursepref = $domdefs{'canuse_pdfforms'};
                   1520:                     }
                   1521:                 }
                   1522:                 if ($coursepref) { 
                   1523:                     $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1524:                 }
1.295     raeburn  1525:             }
                   1526:         } elsif ($pro =~ /^communityenv_(.*)$/) {
                   1527:             my $key = $1;
1.307     raeburn  1528:             if ($crstype eq 'Community') {
                   1529:                 my $coursepref = $env{'course.'.$env{'request.course.id'}.'.'.$key};
                   1530:                 if ($key eq 'canuse_pdfforms') {
                   1531:                     if ($env{'request.course.id'} && $coursepref eq '') {
                   1532:                         my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
                   1533:                         $coursepref = $domdefs{'canuse_pdfforms'};
                   1534:                     }
                   1535:                 }
                   1536:                 if ($coursepref) { 
                   1537:                     $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1538:                 }
1.124     matthew  1539:             }
1.81      matthew  1540:         } elsif ($pro =~ /^course_(.*)$/) {
                   1541:             # Check for permissions inside of a course
1.295     raeburn  1542:             if (($env{'request.course.id'}) && ($crstype ne 'Community') && 
1.152     albertel 1543:                 (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
                   1544:             ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
1.81      matthew  1545:                  )) {
1.209     www      1546:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
1.26      www      1547: 	    }
1.295     raeburn  1548:         } elsif ($pro =~ /^community_(.*)$/) {
                   1549:             # Check for permissions inside of a community
                   1550:             if (($env{'request.course.id'}) && ($crstype eq 'Community') &&   
                   1551:                 (&Apache::lonnet::allowed($1,$env{'request.course.id'}.
                   1552:             ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:''))
                   1553:                  )) {
                   1554:                 $output.=&switch($uname,$udom,$row,$col,$img,$top,$bot,$act,$desc,$cat);
                   1555:             }
1.4       www      1556:         } elsif ($pro eq 'author') {
                   1557:             if ($author) {
1.152     albertel 1558:                 if ((($prt eq 'rca') && ($env{'request.role'}=~/^ca/)) ||
1.234     raeburn  1559:                     (($prt eq 'raa') && ($env{'request.role'}=~/^aa/)) || 
1.152     albertel 1560:                     (($prt eq 'rau') && ($env{'request.role'}=~/^au/))) {
1.19      matthew  1561:                     # Check that we are on the correct machine
1.29      matthew  1562:                     my $cadom=$requested_domain;
1.152     albertel 1563:                     my $caname=$env{'user.name'};
1.234     raeburn  1564:                     if (($prt eq 'rca') || ($prt eq 'raa')) {
1.29      matthew  1565: 		       ($cadom,$caname)=
1.206     albertel 1566:                                ($env{'request.role'}=~/($match_domain)\/($match_username)$/);
1.29      matthew  1567:                     }                       
                   1568:                     $act =~ s/\$caname/$caname/g;
1.353     www      1569:                     $act =~ s/\$cadom/$cadom/g;
1.19      matthew  1570:                     my $home = &Apache::lonnet::homeserver($caname,$cadom);
1.109     albertel 1571: 		    my $allowed=0;
                   1572: 		    my @ids=&Apache::lonnet::current_machine_ids();
                   1573: 		    foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
                   1574: 		    if ($allowed) {
1.209     www      1575:                         $output.=&switch($caname,$cadom,
                   1576:                                         $row,$col,$img,$top,$bot,$act,$desc,$cat);
1.19      matthew  1577:                     }
1.6       www      1578:                 }
1.2       www      1579:             }
1.248     raeburn  1580:         } elsif ($pro eq 'tools') {
                   1581:             my @tools = ('aboutme','blog','portfolio');
                   1582:             if (grep(/^\Q$prt\E$/,@tools)) {
1.249     raeburn  1583:                 if (!&Apache::lonnet::usertools_access($env{'user.name'},
1.251     raeburn  1584:                                                        $env{'user.domain'},
                   1585:                                                        $prt,undef,'tools')) {
                   1586:                     $output.=&clear($row,$col);
                   1587:                     next;
                   1588:                 }
1.278     raeburn  1589:             } elsif (($prt eq 'reqcrsnsc') || ($prt eq 'reqcrsshc')) {
                   1590:                 if (($prt eq 'reqcrsnsc') && ($show_course))   {
                   1591:                     next;
                   1592:                 }
                   1593:                 if (($prt eq 'reqcrsshc') && (!$show_course)) {
                   1594:                     next;
                   1595:                 }
1.279     raeburn  1596:                 my $showreqcrs = &check_for_rcrs();
1.251     raeburn  1597:                 if (!$showreqcrs) {
1.248     raeburn  1598:                     $output.=&clear($row,$col);
                   1599:                     next;
                   1600:                 }
                   1601:             }
                   1602:             $prt='any';
                   1603:             $output.=&secondlevel(
                   1604:           $uname,$udom,$rol,$crs,$pub,$con,$row,$col,$prt,$img,$top,$bot,$act,$desc,$cat);
1.2       www      1605:         }
1.13      harris41 1606:     }
1.2       www      1607:     return $output;
                   1608: }
                   1609: 
1.279     raeburn  1610: sub check_for_rcrs {
                   1611:     my $showreqcrs = 0;
1.443     raeburn  1612:     my @reqtypes = ('official','unofficial','community','textbook','placement');
1.280     raeburn  1613:     foreach my $type (@reqtypes) {
1.279     raeburn  1614:         if (&Apache::lonnet::usertools_access($env{'user.name'},
                   1615:                                               $env{'user.domain'},
                   1616:                                               $type,undef,'requestcourses')) {
                   1617:             $showreqcrs = 1;
                   1618:             last;
                   1619:         }
                   1620:     }
1.280     raeburn  1621:     if (!$showreqcrs) {
                   1622:         foreach my $type (@reqtypes) {
                   1623:             if ($env{'environment.reqcrsotherdom.'.$type} ne '') {
                   1624:                 $showreqcrs = 1;
                   1625:                 last;
                   1626:             }
                   1627:         }
                   1628:     }
1.279     raeburn  1629:     return $showreqcrs;
                   1630: }
                   1631: 
1.306     raeburn  1632: sub dc_popup_js {
                   1633:     my %lt = &Apache::lonlocal::texthash(
                   1634:                                           more => '(More ...)',
                   1635:                                           less => '(Less ...)',
                   1636:                                         );
                   1637:     return <<"END";
                   1638: 
                   1639: function showCourseID() {
                   1640:     document.getElementById('dccid').style.display='block';
                   1641:     document.getElementById('dccid').style.textAlign='left';
1.307     raeburn  1642:     document.getElementById('dccid').style.textFace='normal';
1.369     raeburn  1643:     document.getElementById('dccidtext').innerHTML ='<a href="javascript:hideCourseID();" class="LC_menubuttons_link">$lt{'less'}</a>';
1.306     raeburn  1644:     return;
                   1645: }
                   1646: 
                   1647: function hideCourseID() {
                   1648:     document.getElementById('dccid').style.display='none';
1.369     raeburn  1649:     document.getElementById('dccidtext').innerHTML ='<a href="javascript:showCourseID()" class="LC_menubuttons_link">$lt{'more'}</a>';
1.306     raeburn  1650:     return;
                   1651: }
                   1652: 
                   1653: END
                   1654: 
                   1655: }
                   1656: 
1.378     raeburn  1657: sub countdown_toggle_js {
                   1658:     return <<"END";
                   1659: 
                   1660: function toggleCountdown() {
                   1661:     var countdownid = document.getElementById('duedatecountdown');
                   1662:     var currstyle = countdownid.style.display;
                   1663:     if (currstyle == 'inline') {
                   1664:         countdownid.style.display = 'none';
                   1665:         document.getElementById('ddcountcollapse').innerHTML='';
                   1666:         document.getElementById('ddcountexpand').innerHTML='&#9668;&nbsp;';
                   1667:     } else {
                   1668:         countdownid.style.display = 'inline';
                   1669:         document.getElementById('ddcountcollapse').innerHTML='&#9658;&nbsp;';
                   1670:         document.getElementById('ddcountexpand').innerHTML='';
                   1671:     }
                   1672:     return;
                   1673: }
                   1674: 
                   1675: END
                   1676: }
                   1677: 
1.435     musolffc 1678: # This creates a "done button" for timed events.  The confirmation box is a jQuery
1.440     raeburn  1679: # dialog widget. If the interval parameter requires a proctor key for the timed 
                   1680: # event to be marked done, there will also be a textbox where that can be entered. 
                   1681: # Clicking OK will set the value of LC_interval_done to 'true', and, if needed will 
                   1682: # set the value of LC_interval_done_proctorpass to the text entered in that box, 
                   1683: # and submit the corresponding form.
                   1684: # 
                   1685: # The &zero_time() routine in lonhomework.pm is called when a page is rendered if
                   1686: # LC_interval_done is true.
                   1687: #
1.435     musolffc 1688: sub done_button_js {
1.448     raeburn  1689:     my ($type,$width,$height,$proctor,$donebuttontext) = @_;
1.441     raeburn  1690:     return unless (($type eq 'map') || ($type eq 'resource'));
1.435     musolffc 1691:     my %lt = &Apache::lonlocal::texthash(
                   1692:                  title    => 'WARNING!',
                   1693:                  preamble => 'You are trying to end this timed event early.',
                   1694:                  map      => 'Confirming that you are done will cause the time to expire and prevent you from changing any answers in the current folder.',
                   1695:                  resource => 'Confirming that you are done will cause the time to expire for this question, and prevent you from changing your answer(s).', 
1.440     raeburn  1696:                  okdone   => 'Click "OK" if you are completely finished.',
1.435     musolffc 1697:                  cancel   => 'Click "Cancel" to continue working.',
1.440     raeburn  1698:                  proctor  => 'Ask a proctor to enter the key, then click "OK" if you are completely finished.',
                   1699:                  ok       => 'OK',
                   1700:                  exit     => 'Cancel',
                   1701:                  key      => 'Key:',
                   1702:                  nokey    => 'A proctor key is required', 
1.435     musolffc 1703:     );
1.441     raeburn  1704:     my $navmap = Apache::lonnavmaps::navmap->new(); 
1.450     raeburn  1705:     my ($missing,$tried) = (0,0);
1.441     raeburn  1706:     if (ref($navmap)) {
                   1707:         my @resources=();
                   1708:         if ($type eq 'map') {
                   1709:             my ($mapurl,$rid,$resurl)=&Apache::lonnet::decode_symb($env{'request.symb'});
1.442     raeburn  1710:             @resources=$navmap->retrieveResources($mapurl,sub { $_[0]->is_problem() });
1.441     raeburn  1711:         } else {
                   1712:             my $res = $navmap->getBySymb($env{'request.symb'});
                   1713:             if (ref($res)) {
                   1714:                 if ($res->is_problem()) {
                   1715:                     push(@resources,$res);
                   1716:                 }
                   1717:             }
                   1718:         }
                   1719:         foreach my $res (@resources) {
1.450     raeburn  1720:             if (ref($res->parts()) eq 'ARRAY') {
1.441     raeburn  1721:                 foreach my $part (@{$res->parts()}) {
                   1722:                     if (!$res->tries($part)) {
                   1723:                         $missing++;
                   1724:                     } else {
                   1725:                         $tried++;
                   1726:                     }
                   1727:                 }
                   1728:             }
                   1729:         }
                   1730:     }
                   1731:     if ($missing) {
                   1732:         $lt{'miss'} .= '<p class="LC_error">';
                   1733:         if ($type eq 'map') {
                   1734:             $lt{'miss'} .= &mt('Submissions are missing for [quant,_1,question part,question parts] in this folder.',$missing);
                   1735:         } else {
                   1736:             $lt{'miss'} .= &mt('Submissions are missing for [quant,_1,part] in this question.',$missing);
                   1737:         }
                   1738:         if ($missing > 1) {
                   1739:             $lt{'miss'} .= ' '.&mt('If you confirm you are done you will be unable to submit answers for them.').'</span>';
                   1740:         } else {
                   1741:             $lt{'miss'} .= ' '.&mt('If you confirm you are done you will be unable to submit an answer for it.').'</p>';
                   1742:         }
                   1743:     }
1.449     raeburn  1744:     $donebuttontext = &HTML::Entities::encode($donebuttontext,'<>&"');
1.441     raeburn  1745:     if ($proctor) {
                   1746:         if ($height !~ /^\d+$/) {
                   1747:             $height = 400;
                   1748:             if ($missing) {
                   1749:                 $height += 60; 
1.440     raeburn  1750:             }
1.441     raeburn  1751:         }
                   1752:         if ($width !~ /^\d+$/) {
                   1753:             $width = 400;
                   1754:             if ($missing) {
                   1755:                 $width += 60;
1.440     raeburn  1756:             }
1.441     raeburn  1757:         }
                   1758:         return <<END;
1.440     raeburn  1759: <form method="post" name="LCdoneButton" action="">
                   1760:     <input type="hidden" name="LC_interval_done" value="" />
                   1761:     <input type="hidden" name="LC_interval_done_proctorpass" value="" />
1.448     raeburn  1762:     <button id="LC_done-confirm-opener" type="button">$donebuttontext</button>
1.440     raeburn  1763: </form>
                   1764: 
                   1765: <div id="LC_done-confirm" title="$lt{'title'}">
                   1766:   <p>$lt{'preamble'} $lt{$type}</p>
1.441     raeburn  1767:   $lt{'miss'}
1.440     raeburn  1768:   <p>$lt{'proctor'}</p>
1.449     raeburn  1769:   <form name="LCdoneButtonProctor" action="">
1.440     raeburn  1770:     <label>$lt{'key'}<input type="password" name="LC_interval_done_proctorkey" value="" /></label>
                   1771:     <input type="submit" tabindex="-1" style="position:absolute; top:-1000px" />
                   1772:   </form>
                   1773:   <p>$lt{'cancel'}</p>
                   1774: </div>
                   1775: 
                   1776: <script type="text/javascript">
                   1777: // <![CDATA[
                   1778:     \$( "#LC_done-confirm" ).dialog({ autoOpen: false });
                   1779:     \$( "#LC_done-confirm-opener" ).on("click", function() {
                   1780:         \$( "#LC_done-confirm" ).dialog("open");
                   1781:         \$( "#LC_done-confirm" ).dialog({
                   1782:             height: $height,
                   1783:             width: $width,
                   1784:             modal: true,
                   1785:             resizable: false,
                   1786:             buttons: [
                   1787:                 {
                   1788:                     text: "$lt{'ok'}",
                   1789:                     click: function() {
                   1790:                         var proctorkey = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
                   1791:                         if ((proctorkey == '') || (proctorkey == null)) {
                   1792:                             alert("$lt{'nokey'}"); 
                   1793:                         } else { 
                   1794:                             \$( '[name="LC_interval_done"]' )[0].value = 'true';
                   1795:                             \$( '[name="LC_interval_done_proctorpass"]' )[0].value = proctorkey;
                   1796:                             \$( '[name="LCdoneButton"]' )[0].submit();
                   1797:                         }
                   1798:                     },
                   1799:                 },
                   1800:                 {
                   1801:                     text: "$lt{'exit'}",
                   1802:                     click: function() {
                   1803:                         \$("#LC_done-confirm").dialog( "close" );
                   1804:                     }
                   1805:                 }
                   1806:             ],
                   1807:             close: function() {
                   1808:                 \$( '[name="LC_interval_done_proctorkey"]' )[0].value = '';
                   1809:             }
                   1810:         });
                   1811:         \$( "#LC_done-confirm" ).find( "form" ).on( "submit", function( event ) {
                   1812:             event.preventDefault();
                   1813:             \$( '[name="LC_interval_done"]' )[0].value = 'true';
                   1814:             \$( '[name="LC_interval_done_proctorpass"]' )[0].value = \$( '[name="LC_interval_done_proctorkey"]' )[0].value;
                   1815:             \$( '[name="LCdoneButton"]' )[0].submit();
                   1816:         });
                   1817: });
                   1818: 
                   1819: // ]]>
                   1820: </script>
                   1821: 
                   1822: END
1.441     raeburn  1823:     } else {
                   1824:         if ($height !~ /^\d+$/) {
                   1825:             $height = 320;
                   1826:             if ($missing) {
                   1827:                 $height += 60;
1.440     raeburn  1828:             }
1.441     raeburn  1829:         }
                   1830:         if ($width !~ /^\d+$/) {
                   1831:             $width = 320;
                   1832:             if ($missing) {
                   1833:                 $width += 60;
1.440     raeburn  1834:             }
1.441     raeburn  1835:         }
                   1836:         if ($missing) {
                   1837:             $lt{'miss'} = '</p>'.$lt{'miss'}.'<p>';
                   1838:         }
                   1839:         return <<END;
1.435     musolffc 1840: 
                   1841: <form method="post" name="LCdoneButton" action="">
                   1842:     <input type="hidden" name="LC_interval_done" value="" />
1.449     raeburn  1843:     <button id="LC_done-confirm-opener" type="button">$donebuttontext</button>
1.435     musolffc 1844: </form>
                   1845: 
                   1846: <div id="LC_done-confirm" title="$lt{'title'}">
1.441     raeburn  1847:     <p>$lt{'preamble'} $lt{$type} $lt{'miss'} $lt{'okdone'} $lt{'cancel'}</p>
1.435     musolffc 1848: </div>
                   1849: 
                   1850: <script type="text/javascript">
                   1851: // <![CDATA[
                   1852: \$( "#LC_done-confirm" ).dialog({ autoOpen: false });
                   1853: \$( "#LC_done-confirm-opener" ).click(function() {
                   1854:     \$( "#LC_done-confirm" ).dialog( "open" );
                   1855:     \$( "#LC_done-confirm" ).dialog({
                   1856:       resizable: false,
                   1857:       height: $height,
1.440     raeburn  1858:       width: $width,
1.435     musolffc 1859:       modal: true,
1.440     raeburn  1860:       buttons: [
                   1861:                  {
                   1862:                     text: "$lt{'ok'}",
                   1863:                     click: function() {
                   1864:                         \$( this ).dialog( "close" );
                   1865:                         \$( '[name="LC_interval_done"]' )[0].value = 'true';
                   1866:                         \$( '[name="LCdoneButton"]' )[0].submit();
                   1867:                     },
                   1868:                  },
                   1869:                  {
                   1870:                      text: "$lt{'exit'}",
                   1871:                      click: function() {
                   1872:                          \$( this ).dialog( "close" );
                   1873:                      },
                   1874:                   },
                   1875:                ],
                   1876:        });
1.435     musolffc 1877: });
                   1878: // ]]>
                   1879: </script>
                   1880: 
                   1881: END
                   1882:     }
                   1883: }
                   1884: 
1.42      www      1885: sub utilityfunctions {
1.421     raeburn  1886:     my ($httphost) = @_;
1.152     albertel 1887:     my $currenturl=&Apache::lonnet::clutter(&Apache::lonnet::fixversion((split(/\?/,$env{'request.noversionuri'}))[0]));
1.316     droeschl 1888:     if ($currenturl =~ m{^/adm/wrapper/ext/}
                   1889:         && $env{'request.external.querystring'} ) {
1.293     raeburn  1890:             $currenturl .= ($currenturl=~/\?/)?'&':'?'.$env{'request.external.querystring'};
                   1891:     }
1.183     www      1892:     $currenturl=&Apache::lonenc::check_encrypt(&unescape($currenturl));
1.125     albertel 1893:     
1.152     albertel 1894:     my $currentsymb=&Apache::lonenc::check_encrypt($env{'request.symb'});
1.175     albertel 1895: 
1.306     raeburn  1896:     my $dc_popup_cid;
                   1897:     if ($env{'user.adv'} && exists($env{'user.role.dc./'.
                   1898:                         $env{'course.'.$env{'request.course.id'}.
                   1899:                                  '.domain'}.'/'})) {
                   1900:         $dc_popup_cid = &dc_popup_js();
                   1901:     }
                   1902: 
1.175     albertel 1903:     my $start_page_annotate = 
                   1904:         &Apache::loncommon::start_page('Annotator',undef,
                   1905: 				       {'only_body' => 1,
                   1906: 					'js_ready'  => 1,
                   1907: 					'bgcolor'   => '#BBBBBB',
                   1908: 					'add_entries' => {
                   1909: 					    'onload' => 'javascript:document.goannotate.submit();'}});
                   1910: 
1.205     albertel 1911:     my $end_page_annotate = 
                   1912:         &Apache::loncommon::end_page({'js_ready' => 1});
                   1913: 
1.389     raeburn  1914:     my $jumptores = &Apache::lonhtmlcommon::javascript_jumpto_resource();
1.336     raeburn  1915: 
1.368     www      1916:     my $esc_url=&escape($currenturl);
                   1917:     my $esc_symb=&escape($currentsymb);
1.332     wenzelju 1918: 
1.378     raeburn  1919:     my $countdown = &countdown_toggle_js();
                   1920: 
1.429     raeburn  1921:     my $hostvar = '
                   1922: function setLCHost() {
                   1923:     var lcHostname="";
                   1924: ';
                   1925:     if ($httphost =~ m{^https?\://}) {
                   1926:         $hostvar .= '    var lcServer="'.$httphost.'";'."\n".
                   1927:                     '    var hostReg = /^https?:\/\/([^\/]+)$/i;'."\n".
                   1928:                     '    var match = hostReg.exec(lcServer);'."\n".
                   1929:                     '    if (match.length) {'."\n".
                   1930:                     '        if (match[1] == location.hostname) {'."\n".
                   1931:                     '            lcHostname=lcServer;'."\n".
                   1932:                     '        }'."\n".
                   1933:                     '    }'."\n";
                   1934:     }
                   1935:     
                   1936:     $hostvar .= '    return lcHostname;'."\n".
                   1937: '}'."\n";
                   1938: 
1.42      www      1939: return (<<ENDUTILITY)
1.429     raeburn  1940:     $hostvar
1.368     www      1941:     var currentURL=unescape("$esc_url");
                   1942:     var reloadURL=unescape("$esc_url");
                   1943:     var currentSymb=unescape("$esc_symb");
1.42      www      1944: 
1.306     raeburn  1945: $dc_popup_cid
1.114     albertel 1946: 
1.389     raeburn  1947: $jumptores
1.336     raeburn  1948: 
1.42      www      1949: function gopost(url,postdata) {
                   1950:    if (url!='') {
1.429     raeburn  1951:       var lcHostname = setLCHost();
                   1952:       this.document.server.action=lcHostname+url;
1.42      www      1953:       this.document.server.postdata.value=postdata;
                   1954:       this.document.server.command.value='';
                   1955:       this.document.server.url.value='';
                   1956:       this.document.server.symb.value='';
                   1957:       this.document.server.submit();
                   1958:    }
                   1959: }
                   1960: 
                   1961: function gocmd(url,cmd) {
                   1962:    if (url!='') {
1.429     raeburn  1963:       var lcHostname = setLCHost();
                   1964:       this.document.server.action=lcHostname+url;
1.42      www      1965:       this.document.server.postdata.value='';
                   1966:       this.document.server.command.value=cmd;
                   1967:       this.document.server.url.value=currentURL;
                   1968:       this.document.server.symb.value=currentSymb;
                   1969:       this.document.server.submit();
                   1970:    }
1.57      www      1971: }
                   1972: 
1.121     raeburn  1973: function gocstr(url,filename) {
                   1974:     if (url == '/adm/cfile?action=delete') {
                   1975:         this.document.cstrdelete.filename.value = filename
                   1976:         this.document.cstrdelete.submit();
                   1977:         return;
                   1978:     }
1.137     raeburn  1979:     if (url == '/adm/printout') {
                   1980:         this.document.cstrprint.postdata.value = filename
                   1981:         this.document.cstrprint.curseed.value = 0;
                   1982:         this.document.cstrprint.problemtype.value = 0;
1.138     raeburn  1983:         if (this.document.lonhomework) {
                   1984:             if ((this.document.lonhomework.rndseed) && (this.document.lonhomework.rndseed.value != null) && (this.document.lonhomework.rndseed.value != '')) {
                   1985:                 this.document.cstrprint.curseed.value = this.document.lonhomework.rndseed.value
                   1986:             }
                   1987:             if (this.document.lonhomework.problemtype) {
1.164     albertel 1988: 		if (this.document.lonhomework.problemtype.value) {
                   1989: 		    this.document.cstrprint.problemtype.value = 
                   1990: 			this.document.lonhomework.problemtype.value;
                   1991: 		} else if (this.document.lonhomework.problemtype.options) {
                   1992: 		    for (var i=0; i<this.document.lonhomework.problemtype.options.length; i++) {
                   1993: 			if (this.document.lonhomework.problemtype.options[i].selected) {
                   1994: 			    if (this.document.lonhomework.problemtype.options[i].value != null && this.document.lonhomework.problemtype.options[i].value != '') { 
                   1995: 				this.document.cstrprint.problemtype.value = this.document.lonhomework.problemtype.options[i].value
                   1996: 				}
                   1997: 			}
                   1998: 		    }
                   1999: 		}
                   2000: 	    }
                   2001: 	}
1.137     raeburn  2002:         this.document.cstrprint.submit();
                   2003:         return;
                   2004:     }
1.121     raeburn  2005:     if (url !='') {
                   2006:         this.document.constspace.filename.value = filename;
                   2007:         this.document.constspace.action = url;
                   2008:         this.document.constspace.submit();
                   2009:     }
                   2010: }
                   2011: 
1.131     raeburn  2012: function golist(url) {
                   2013:    if (url!='' && url!= null) {
                   2014:        currentURL = null;
                   2015:        currentSymb= null;
1.429     raeburn  2016:        var lcHostname = setLCHost();
                   2017:        top.location.href=lcHostname+url;
1.131     raeburn  2018:    }
                   2019: }
                   2020: 
                   2021: 
1.121     raeburn  2022: 
1.428     raeburn  2023: function catalog_info(isMobile) {
                   2024:     if (isMobile == 1) {
                   2025:         openMyModal(window.location.pathname+'.meta?modal=1',500,400,'yes');
                   2026:     } else {
                   2027:         loncatinfo=window.open(window.location.pathname+'.meta',"LONcatInfo",'height=500,width=400,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
                   2028:     }
1.57      www      2029: }
                   2030: 
                   2031: function chat_win() {
1.429     raeburn  2032:    var lcHostname = setLCHost();
                   2033:    lonchat=window.open(lcHostname+'/res/adm/pages/chatroom.html',"LONchat",'height=320,width=480,resizable=yes,location=no,menubar=no,toolbar=no');
1.42      www      2034: }
1.169     raeburn  2035: 
                   2036: function group_chat(group) {
1.429     raeburn  2037:    var lcHostname = setLCHost();
                   2038:    var url = lcHostname+'/adm/groupchat?group='+group;
1.169     raeburn  2039:    var winName = 'LONchat_'+group;
                   2040:    grpchat=window.open(url,winName,'height=320,width=280,resizable=yes,location=no,menubar=no,toolbar=no');
                   2041: }
1.175     albertel 2042: 
                   2043: function annotate() {
                   2044:    w_Annotator_flag=1;
                   2045:    annotator=window.open('','Annotator','width=365,height=265,scrollbars=0');
                   2046:    annotator.document.write(
                   2047:    '$start_page_annotate'
                   2048:   +"<form name='goannotate' target='Annotator' method='post' "
                   2049:   +"action='/adm/annotations'>"
1.217     albertel 2050:   +"<input type='hidden' name='symbnew' value='"+currentSymb+"' />"
1.181     albertel 2051:   +"<\\/form>"
1.205     albertel 2052:   +'$end_page_annotate');
1.175     albertel 2053:    annotator.document.close();
                   2054: }
                   2055: 
1.370     raeburn  2056: function open_StoredLinks_Import(rat) {
1.335     wenzelju 2057:    var newWin;
1.429     raeburn  2058:    var lcHostname = setLCHost();
1.335     wenzelju 2059:    if (rat) {
1.429     raeburn  2060:        newWin = window.open(lcHostname+'/adm/wishlist?inhibitmenu=yes&mode=import&rat='+rat,
1.334     wenzelju 2061:                             'wishlistImport','scrollbars=1,resizable=1,menubar=0');
1.335     wenzelju 2062:    }
                   2063:    else {
1.429     raeburn  2064:        newWin = window.open(lcHostname+'/adm/wishlist?inhibitmenu=yes&mode=import',
1.335     wenzelju 2065:                             'wishlistImport','scrollbars=1,resizable=1,menubar=0');
                   2066:    }
1.334     wenzelju 2067:    newWin.focus();
                   2068: }
                   2069: 
1.372     raeburn  2070: (function (\$) {
                   2071:   \$(document).ready(function () {
                   2072:     \$.single=function(a){return function(b){a[0]=b;return a}}(\$([1]));
                   2073:     /*\@cc_on
                   2074:       if (!window.XMLHttpRequest) {
                   2075:         \$('.LC_hoverable').each(function () {
                   2076:           this.attachEvent('onmouseenter', function (evt) { \$.single(evt.srcElement).addClass('hover'); });
                   2077:           this.attachEvent('onmouseleave', function (evt) { \$.single(evt.srcElement).removeClass('hover'); });
                   2078:         });
                   2079:       }
                   2080:     \@*/
                   2081:   });
                   2082: }(jQuery));
                   2083: 
1.378     raeburn  2084: $countdown
                   2085: 
1.42      www      2086: ENDUTILITY
                   2087: }
                   2088: 
                   2089: sub serverform {
                   2090:     return(<<ENDSERVERFORM);
1.181     albertel 2091: <form name="server" action="/adm/logout" method="post" target="_top">
1.42      www      2092: <input type="hidden" name="postdata" value="none" />
                   2093: <input type="hidden" name="command" value="none" />
                   2094: <input type="hidden" name="url" value="none" />
                   2095: <input type="hidden" name="symb" value="none" />
                   2096: </form>
                   2097: ENDSERVERFORM
                   2098: }
1.113     albertel 2099: 
1.121     raeburn  2100: sub constspaceform {
                   2101:     return(<<ENDCONSTSPACEFORM);
1.181     albertel 2102: <form name="constspace" action="/adm/logout" method="post" target="_top">
1.121     raeburn  2103: <input type="hidden" name="filename" value="" />
                   2104: </form>
1.181     albertel 2105: <form name="cstrdelete" action="/adm/cfile" method="post" target="_top">
1.121     raeburn  2106: <input type="hidden" name="action" value="delete" /> 
                   2107: <input type="hidden" name="filename" value="" />
                   2108: </form>
1.181     albertel 2109: <form name="cstrprint" action="/adm/printout" target="_parent" method="post">
1.137     raeburn  2110: <input type="hidden" name="postdata" value="" />
                   2111: <input type="hidden" name="curseed" value="" />
                   2112: <input type="hidden" name="problemtype" value="" />
                   2113: </form>
                   2114: 
1.121     raeburn  2115: ENDCONSTSPACEFORM
                   2116: }
                   2117: 
1.220     raeburn  2118: sub hidden_button_check {
1.317     droeschl 2119:     if ( $env{'request.course.id'} eq ''
                   2120:          || $env{'request.role.adv'} ) {
                   2121: 
1.220     raeburn  2122:         return;
                   2123:     }
1.232     raeburn  2124:     my $buttonshide = &Apache::lonnet::EXT('resource.0.buttonshide');
                   2125:     return $buttonshide; 
1.220     raeburn  2126: }
1.184     raeburn  2127: 
1.235     raeburn  2128: sub roles_selector {
1.421     raeburn  2129:     my ($cdom,$cnum,$httphost) = @_;
1.298     raeburn  2130:     my $crstype = &Apache::loncommon::course_type();
1.235     raeburn  2131:     my $now = time;
1.465     raeburn  2132:     my (%courseroles,%seccount,%courseprivs,%roledesc);
1.235     raeburn  2133:     my $is_cc;
1.432     droeschl 2134:     my ($js,$form,$switcher);
1.298     raeburn  2135:     my $ccrole;
                   2136:     if ($crstype eq 'Community') {
                   2137:         $ccrole = 'co';
                   2138:     } else {
                   2139:         $ccrole = 'cc';
1.350     raeburn  2140:     }
1.457     raeburn  2141:     my ($privref,$gotsymb,$destsymb);
1.350     raeburn  2142:     my $destinationurl = $ENV{'REQUEST_URI'};
1.468     raeburn  2143:     if ($destinationurl =~ /(\?|\&)symb=/) {
1.386     raeburn  2144:         $gotsymb = 1;
                   2145:     } elsif ($destinationurl =~ m{^/enc/}) {
                   2146:         my $plainurl = &Apache::lonenc::unencrypted($destinationurl);
1.468     raeburn  2147:         if ($plainurl =~ /(\?|\&)symb=/) {
1.386     raeburn  2148:             $gotsymb = 1;
                   2149:         }
                   2150:     }
                   2151:     unless ($gotsymb) {
                   2152:         $destsymb = &Apache::lonnet::symbread();
                   2153:         if ($destsymb ne '') {
                   2154:             $destsymb = &Apache::lonenc::check_encrypt($destsymb);
                   2155:         }
                   2156:     }
1.350     raeburn  2157:     my $reqprivs = &required_privs();
                   2158:     if (ref($reqprivs) eq 'HASH') {
                   2159:         my $destination = $destinationurl;
                   2160:         $destination =~ s/(\?.*)$//;
                   2161:         if (exists($reqprivs->{$destination})) {
1.457     raeburn  2162:             if ($reqprivs->{$destination} =~ /,/) {
                   2163:                 @{$privref} = split(/,/,$reqprivs->{$destination});
                   2164:             } else { 
                   2165:                 $privref = [$reqprivs->{$destination}];
                   2166:             }
1.350     raeburn  2167:         }
                   2168:     }
1.298     raeburn  2169:     if ($env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum}) {
                   2170:         my ($start,$end) = split(/\./,$env{'user.role.'.$ccrole.'./'.$cdom.'/'.$cnum});
1.235     raeburn  2171:         if ((($start) && ($start<0)) || 
                   2172:             (($end) && ($end<$now))  ||
                   2173:             (($start) && ($now<$start))) {
                   2174:             $is_cc = 0;
                   2175:         } else {
                   2176:             $is_cc = 1;
                   2177:         }
                   2178:     }
                   2179:     if ($is_cc) {
1.457     raeburn  2180:         &get_all_courseroles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs);
                   2181:     } elsif ($env{'request.role'} =~ m{^\Qcr/$cdom/$cdom-domainconfig/\E(\w+)\.\Q/$cdom/$cnum\E}) {
1.465     raeburn  2182:         &get_customadhoc_roles($cdom,$cnum,\%courseroles,\%seccount,\%courseprivs,\%roledesc,$privref);
1.235     raeburn  2183:     } else {
1.262     raeburn  2184:         my %gotnosection;
1.235     raeburn  2185:         foreach my $item (keys(%env)) {
1.239     raeburn  2186:             if ($item =~ m-^user\.role\.([^.]+)\./\Q$cdom\E/\Q$cnum\E/?(\w*)$-) {
1.235     raeburn  2187:                 my $role = $1;
                   2188:                 my $sec = $2;
                   2189:                 next if ($role eq 'gr');
                   2190:                 my ($start,$end) = split(/\./,$env{$item});
                   2191:                 next if (($start && $start > $now) || ($end && $end < $now));
                   2192:                 if ($sec eq '') {
1.239     raeburn  2193:                     if (!$gotnosection{$role}) {
                   2194:                         $seccount{$role} ++;
                   2195:                         $gotnosection{$role} = 1;
                   2196:                     }
1.235     raeburn  2197:                 }
1.457     raeburn  2198:                 if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0)) {
1.350     raeburn  2199:                     my $cnumsec = $cnum;
                   2200:                     if ($sec ne '') {
                   2201:                         $cnumsec .= "/$sec";
                   2202:                     }
                   2203:                     $courseprivs{"$role./$cdom/$cnumsec./"} =
                   2204:                         $env{"user.priv.$role./$cdom/$cnumsec./"};
                   2205:                     $courseprivs{"$role./$cdom/$cnumsec./$cdom/"} =
                   2206:                         $env{"user.priv.$role./$cdom/$cnumsec./$cdom/"};
                   2207:                     $courseprivs{"$role./$cdom/$cnumsec./$cdom/$cnumsec"} =
                   2208:                         $env{"user.priv.$role./$cdom/$cnumsec./$cdom/$cnumsec"};
                   2209:                 }
1.235     raeburn  2210:                 if (ref($courseroles{$role}) eq 'ARRAY') {
1.239     raeburn  2211:                     if ($sec ne '') {
1.264     raeburn  2212:                         if (!grep(/^\Q$sec\E$/,@{$courseroles{$role}})) {
1.239     raeburn  2213:                             push(@{$courseroles{$role}},$sec);
                   2214:                             $seccount{$role} ++;
                   2215:                         }
                   2216:                     }
                   2217:                 } else {
                   2218:                     @{$courseroles{$role}} = ();
                   2219:                     if ($sec ne '') {
                   2220:                         $seccount{$role} ++;
1.235     raeburn  2221:                         push(@{$courseroles{$role}},$sec);
                   2222:                     }
                   2223:                 }
                   2224:             }
                   2225:         }
                   2226:     }
1.298     raeburn  2227:     my @roles_order = ($ccrole,'in','ta','ep','ad','st');
1.402     raeburn  2228:     my $numdiffsec;
                   2229:     if (keys(%seccount) == 1) {
                   2230:         foreach my $key (keys(%seccount)) {
                   2231:             $numdiffsec = $seccount{$key};
                   2232:         }
                   2233:     }
                   2234:     if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {
1.401     raeburn  2235:         my @submenu;
1.465     raeburn  2236:         $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,\%roledesc,$privref);
1.401     raeburn  2237:         $form = 
1.421     raeburn  2238:             '<form name="rolechooser" method="post" action="'.$httphost.'/adm/roles">'."\n".
1.401     raeburn  2239:             '  <input type="hidden" name="destinationurl" value="'.
                   2240:             &HTML::Entities::encode($destinationurl).'" />'."\n".
                   2241:             '  <input type="hidden" name="gotorole" value="1" />'."\n".
                   2242:             '  <input type="hidden" name="selectrole" value="" />'."\n".
1.402     raeburn  2243:             '  <input type="hidden" name="switchrole" value="" />'."\n";
                   2244:         if ($destsymb ne '') {
                   2245:             $form .= '  <input type="hidden" name="destsymb" value="'.
                   2246:                         &HTML::Entities::encode($destsymb).'" />'."\n";
                   2247:         }
                   2248:         $form .= '</form>'."\n";
1.235     raeburn  2249:         foreach my $role (@roles_order) {
1.402     raeburn  2250:             my $include;
1.235     raeburn  2251:             if (defined($courseroles{$role})) {
1.402     raeburn  2252:                 if ($env{'request.role'} =~ m{^\Q$role\E}) {
                   2253:                     if ($seccount{$role} > 1) {
                   2254:                         $include = 1;
                   2255:                     }
                   2256:                 } else {
                   2257:                     $include = 1;
                   2258:                 }
                   2259:             }
                   2260:             if ($include) {
1.401     raeburn  2261:                 push(@submenu,['javascript:adhocRole('."'$role'".')',
                   2262:                                &Apache::lonnet::plaintext($role,$crstype)]);
1.235     raeburn  2263:             }
                   2264:         }
                   2265:         foreach my $role (sort(keys(%courseroles))) {
                   2266:             if ($role =~ /^cr/) {
1.403     raeburn  2267:                 my $include;
                   2268:                 if ($env{'request.role'} =~ m{^\Q$role\E}) {
1.402     raeburn  2269:                     if ($seccount{$role} > 1) {
                   2270:                         $include = 1;
                   2271:                     }
1.403     raeburn  2272:                 } else {
                   2273:                     $include = 1; 
                   2274:                 }
                   2275:                 if ($include) {
1.460     raeburn  2276:                     my $rolename;
                   2277:                     if ($role =~ m{^cr/$cdom/$cdom\-domainconfig/(\w+)(?:/\w+|$)}) {
1.465     raeburn  2278:                         $rolename = $roledesc{$role};
                   2279:                         if ($rolename eq '') {
                   2280:                             $rolename = &mt('Helpdesk [_1]',$1);
                   2281:                         }
1.460     raeburn  2282:                     } else {
                   2283:                         $rolename = &Apache::lonnet::plaintext($role);
                   2284:                     }
1.403     raeburn  2285:                     push(@submenu,['javascript:adhocRole('."'$role'".')',
1.460     raeburn  2286:                                    $rolename]);
1.403     raeburn  2287:                 }
1.235     raeburn  2288:             }
                   2289:         }
1.401     raeburn  2290:         if (@submenu > 0) {
1.432     droeschl 2291:             $switcher = &create_submenu('','',&mt('Switch role'),\@submenu);
1.386     raeburn  2292:         }
1.235     raeburn  2293:     }
1.401     raeburn  2294:     return ($js,$form,$switcher);
1.235     raeburn  2295: }
                   2296: 
1.262     raeburn  2297: sub get_all_courseroles {
1.350     raeburn  2298:     my ($cdom,$cnum,$courseroles,$seccount,$courseprivs) = @_;
1.351     raeburn  2299:     unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH') &&
1.350     raeburn  2300:             (ref($courseprivs) eq 'HASH')) {
1.262     raeburn  2301:         return;
                   2302:     }
                   2303:     my ($result,$cached) = 
                   2304:         &Apache::lonnet::is_cached_new('getcourseroles',$cdom.'_'.$cnum);
                   2305:     if (defined($cached)) {
                   2306:         if (ref($result) eq 'HASH') {
                   2307:             if ((ref($result->{'roles'}) eq 'HASH') && 
1.350     raeburn  2308:                 (ref($result->{'seccount'}) eq 'HASH') && 
                   2309:                 (ref($result->{'privs'}) eq 'HASH')) {
1.262     raeburn  2310:                 %{$courseroles} = %{$result->{'roles'}};
                   2311:                 %{$seccount} = %{$result->{'seccount'}};
1.350     raeburn  2312:                 %{$courseprivs} = %{$result->{'privs'}};
1.262     raeburn  2313:                 return;
                   2314:             }
                   2315:         }
                   2316:     }
                   2317:     my %gotnosection;
                   2318:     my %adv_roles =
                   2319:          &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
                   2320:     foreach my $role (keys(%adv_roles)) {
                   2321:         my ($urole,$usec) = split(/:/,$role);
                   2322:         if (!$gotnosection{$urole}) {
                   2323:             $seccount->{$urole} ++;
                   2324:             $gotnosection{$urole} = 1;
                   2325:         }
                   2326:         if (ref($courseroles->{$urole}) eq 'ARRAY') {
                   2327:             if ($usec ne '') {
                   2328:                 if (!grep(/^Q$usec\E$/,@{$courseroles->{$urole}})) {
                   2329:                     push(@{$courseroles->{$urole}},$usec);
                   2330:                     $seccount->{$urole} ++;
                   2331:                 }
                   2332:             }
                   2333:         } else {
                   2334:             @{$courseroles->{$urole}} = ();
                   2335:             if ($usec ne '') {
                   2336:                 $seccount->{$urole} ++;
                   2337:                 push(@{$courseroles->{$urole}},$usec);
                   2338:             }
                   2339:         }
1.350     raeburn  2340:         my $area = '/'.$cdom.'/'.$cnum;
                   2341:         if ($usec ne '') {
                   2342:             $area .= '/'.$usec;
                   2343:         }
                   2344:         if ($role =~ /^cr\//) {
                   2345:             &Apache::lonnet::custom_roleprivs($courseprivs,$urole,$cdom,$cnum,$urole.'.'.$area,$area);
                   2346:         } else {
                   2347:             &Apache::lonnet::standard_roleprivs($courseprivs,$urole,$cdom,$urole.'.'.$area,$cnum,$area);
                   2348:         }
1.262     raeburn  2349:     }
                   2350:     my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum,['st']);
                   2351:     @{$courseroles->{'st'}} = ();
1.350     raeburn  2352:     &Apache::lonnet::standard_roleprivs($courseprivs,'st',$cdom,"st./$cdom/$cnum",$cnum,"/$cdom/$cnum");
1.262     raeburn  2353:     if (keys(%sections_count) > 0) {
                   2354:         push(@{$courseroles->{'st'}},keys(%sections_count));
1.350     raeburn  2355:         $seccount->{'st'} = scalar(keys(%sections_count));
1.262     raeburn  2356:     }
1.410     raeburn  2357:     $seccount->{'st'} ++; # Increment for a section-less student role.  
1.262     raeburn  2358:     my $rolehash = {
                   2359:                      'roles'    => $courseroles,
                   2360:                      'seccount' => $seccount,
1.350     raeburn  2361:                      'privs'    => $courseprivs,
1.262     raeburn  2362:                    };
                   2363:     &Apache::lonnet::do_cache_new('getcourseroles',$cdom.'_'.$cnum,$rolehash);
                   2364:     return;
                   2365: }
                   2366: 
1.457     raeburn  2367: sub get_customadhoc_roles {
1.465     raeburn  2368:     my ($cdom,$cnum,$courseroles,$seccount,$courseprivs,$roledesc,$privref) = @_;
1.457     raeburn  2369:     unless ((ref($courseroles) eq 'HASH') && (ref($seccount) eq 'HASH') &&
1.465     raeburn  2370:             (ref($courseprivs) eq 'HASH') && (ref($roledesc) eq 'HASH')) {
1.457     raeburn  2371:         return;
                   2372:     }
1.466     raeburn  2373:     my $is_helpdesk = 0;
                   2374:     my $now = time;
                   2375:     foreach my $role ('dh','da') {
                   2376:         if ($env{"user.role.$role./$cdom/"}) {
                   2377:             my ($start,$end)=split(/\./,$env{"user.role.$role./$cdom/"});
                   2378:             if (!($start && ($now<$start)) && !($end && ($now>$end))) {
                   2379:                 $is_helpdesk = 1;
                   2380:                 last;
                   2381:             }
                   2382:         }
                   2383:     }
                   2384:     if ($is_helpdesk) {
                   2385:         my ($possroles,$description) = &Apache::lonnet::get_my_adhocroles($cdom.'_'.$cnum);
                   2386:         my %available;
                   2387:         if (ref($possroles) eq 'ARRAY') {
                   2388:             map { $available{$_} = 1; } @{$possroles};
                   2389:         }
                   2390:         my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom);
                   2391:         if (ref($domdefaults{'adhocroles'}) eq 'HASH') {
                   2392:             if (keys(%{$domdefaults{'adhocroles'}})) {
                   2393:                 my $numsec = 1;
                   2394:                 my @sections;
                   2395:                 my ($allseclist,$cached) =
                   2396:                     &Apache::lonnet::is_cached_new('courseseclist',$cdom.'_'.$cnum);
                   2397:                 if (defined($cached)) {
                   2398:                     if ($allseclist ne '') {
                   2399:                         @sections = split(/,/,$allseclist);
1.465     raeburn  2400:                         $numsec += scalar(@sections);
1.457     raeburn  2401:                     }
1.466     raeburn  2402:                 } else {
                   2403:                     my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum);
                   2404:                     @sections = sort(keys(%sections_count));
                   2405:                     $numsec += scalar(@sections);
                   2406:                     $allseclist = join(',',@sections);
                   2407:                     &Apache::lonnet::do_cache_new('courseseclist',$cdom.'_'.$cnum,$allseclist);
                   2408:                 }
                   2409:                 my (%adhoc,$gotprivs);
                   2410:                 my $prefix = "cr/$cdom/$cdom".'-domainconfig';
                   2411:                 foreach my $role (keys(%{$domdefaults{'adhocroles'}})) {
                   2412:                     next if (($role eq '') || ($role =~ /\W/));
                   2413:                     $seccount->{"$prefix/$role"} = $numsec;
                   2414:                     $roledesc->{"$prefix/$role"} = $description->{$role};
                   2415:                     if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0)) {
                   2416:                         if (exists($env{"user.priv.$prefix/$role./$cdom/$cnum./"})) {
                   2417:                             $courseprivs->{"$prefix/$role./$cdom/$cnum./"} =
                   2418:                                 $env{"user.priv.$prefix/$role./$cdom/$cnum./"};
                   2419:                             $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/"} =
                   2420:                                 $env{"user.priv.$prefix/$role./$cdom/$cnum./$cdom/"};
                   2421:                             $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/$cnum"} =
                   2422:                                 $env{"user.priv.$prefix/$role./$cdom/$cnum./$cdom/$cnum"};
                   2423:                         } else {
                   2424:                             unless ($gotprivs) {
                   2425:                                 my ($adhocroles,$privscached) =
                   2426:                                     &Apache::lonnet::is_cached_new('adhocroles',$cdom);
                   2427:                                 if ((defined($privscached)) && (ref($adhocroles) eq 'HASH')) {
                   2428:                                     %adhoc = %{$adhocroles};
                   2429:                                 } else {
                   2430:                                     my $confname = &Apache::lonnet::get_domainconfiguser($cdom);
                   2431:                                     my %roledefs = &Apache::lonnet::dump('roles',$cdom,$confname,'rolesdef_');
                   2432:                                     foreach my $key (keys(%roledefs)) {
                   2433:                                         (undef,my $rolename) = split(/_/,$key);
                   2434:                                         if ($rolename ne '') {
                   2435:                                             my ($systempriv,$domainpriv,$coursepriv) = split(/\_/,$roledefs{$key});
                   2436:                                             $coursepriv = &Apache::lonnet::course_adhocrole_privs($rolename,$cdom,$cnum,$coursepriv);
                   2437:                                             $adhoc{$rolename} = join('_',($systempriv,$domainpriv,$coursepriv));
1.457     raeburn  2438:                                         }
                   2439:                                     }
1.466     raeburn  2440:                                     &Apache::lonnet::do_cache_new('adhocroles',$cdom,\%adhoc);
1.457     raeburn  2441:                                 }
1.466     raeburn  2442:                                 $gotprivs = 1;
1.457     raeburn  2443:                             }
1.466     raeburn  2444:                             ($courseprivs->{"$prefix/$role./$cdom/$cnum./"},
                   2445:                              $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/"},
                   2446:                              $courseprivs->{"$prefix/$role./$cdom/$cnum./$cdom/$cnum"}) =
                   2447:                                  split(/\_/,$adhoc{$role});
1.457     raeburn  2448:                         }
1.466     raeburn  2449:                     }
                   2450:                     if ($available{$role}) {
                   2451:                         $courseroles->{"$prefix/$role"} = \@sections;
1.457     raeburn  2452:                     }
                   2453:                 }
                   2454:             }
                   2455:         }
                   2456:     }
                   2457:     return;
                   2458: }
                   2459: 
1.235     raeburn  2460: sub jump_to_role {
1.465     raeburn  2461:     my ($cdom,$cnum,$seccount,$courseroles,$courseprivs,$roledesc,$privref) = @_;
1.239     raeburn  2462:     my %lt = &Apache::lonlocal::texthash(
                   2463:                 this => 'This role has section(s) associated with it.',
                   2464:                 ente => 'Enter a specific section.',
                   2465:                 orlb => 'Enter a specific section, or leave blank for no section.',
                   2466:                 avai => 'Available sections are:',
                   2467:                 youe => 'You entered an invalid section choice:',
1.352     raeburn  2468:                 plst => 'Please try again.',
1.350     raeburn  2469:                 role => 'The role you selected is not permitted to view the current page.',
                   2470:                 swit => 'Switch role, but display Main Menu page instead?',
1.239     raeburn  2471:     );
                   2472:     my $js;
                   2473:     if (ref($courseroles) eq 'HASH') {
                   2474:         $js = '    var secpick = new Array("'.$lt{'ente'}.'","'.$lt{'orlb'}.'");'."\n". 
                   2475:               '    var numsec = new Array();'."\n".
                   2476:               '    var rolesections = new Array();'."\n".
                   2477:               '    var rolenames = new Array();'."\n".
                   2478:               '    var roleseclist = new Array();'."\n";
                   2479:         my @items = keys(%{$courseroles});
                   2480:         for (my $i=0; $i<@items; $i++) {
                   2481:             $js .= '    rolenames['.$i.'] = "'.$items[$i].'";'."\n";
                   2482:             my ($secs,$secstr);
                   2483:             if (ref($courseroles->{$items[$i]}) eq 'ARRAY') {
                   2484:                 my @sections = sort { $a <=> $b } @{$courseroles->{$items[$i]}};
                   2485:                 $secs = join('","',@sections);
                   2486:                 $secstr = join(', ',@sections);
                   2487:             }
                   2488:             $js .= '    rolesections['.$i.'] = new Array("'.$secs.'");'."\n".
                   2489:                    '    roleseclist['.$i.'] = "'.$secstr.'";'."\n".
                   2490:                    '    numsec['.$i.'] = "'.$seccount->{$items[$i]}.'";'."\n";
                   2491:         }
                   2492:     }
1.350     raeburn  2493:     my $checkroles = 0;
1.457     raeburn  2494:     if ((ref($privref) eq 'ARRAY') && (@{$privref} > 0) && (ref($courseprivs) eq 'HASH')) {
                   2495:         my %disallowed;
1.350     raeburn  2496:         foreach my $role (sort(keys(%{$courseprivs}))) {
                   2497:             my $trole;
                   2498:             if ($role =~ m{^(.+?)\Q./$cdom/$cnum\E}) {
                   2499:                 $trole = $1;
                   2500:             }
                   2501:             if (($trole ne '') && ($trole ne 'cm')) {
1.457     raeburn  2502:                 $disallowed{$trole} = 1;
                   2503:                 foreach my $priv (@{$privref}) { 
                   2504:                     if ($courseprivs->{$role} =~ /\Q:$priv\E($|:|\&\w+)/) {
                   2505:                         delete($disallowed{$trole});
                   2506:                         last;
                   2507:                     }
1.350     raeburn  2508:                 }
                   2509:             }
                   2510:         }
1.457     raeburn  2511:         if (keys(%disallowed) > 0) {
1.350     raeburn  2512:             $checkroles = 1;
1.457     raeburn  2513:             $js .= "    var disallow = new Array('".join("','",keys(%disallowed))."');\n".
1.350     raeburn  2514:                    "    var rolecheck = 1;\n";
                   2515:         }
                   2516:     }
                   2517:     if (!$checkroles) {
                   2518:         $js .=  "    var disallow = new Array();\n".
                   2519:                 "    rolecheck = 0;\n";
                   2520:     }
1.273     droeschl 2521:     return <<"END";
1.235     raeburn  2522: <script type="text/javascript">
1.273     droeschl 2523: //<![CDATA[
1.401     raeburn  2524: function adhocRole(newrole) {
1.239     raeburn  2525:     $js
1.235     raeburn  2526:     if (newrole == '') {
1.350     raeburn  2527:         return;
1.235     raeburn  2528:     } 
1.239     raeburn  2529:     var fullrole = newrole+'./$cdom/$cnum';
                   2530:     var selidx = '';
                   2531:     for (var i=0; i<rolenames.length; i++) {
                   2532:         if (rolenames[i] == newrole) {
                   2533:             selidx = i;
                   2534:         }
                   2535:     }
1.350     raeburn  2536:     if (rolecheck > 0) {
                   2537:         for (var i=0; i<disallow.length; i++) {
                   2538:             if (disallow[i] == newrole) {
                   2539:                 if (confirm("$lt{'role'}\\n$lt{'swit'}")) {
                   2540:                     document.rolechooser.destinationurl.value = '/adm/menu';
                   2541:                 } else {
                   2542:                     return;
                   2543:                 }
                   2544:             }
                   2545:         }
                   2546:     }
1.239     raeburn  2547:     var secok = 1;
                   2548:     var secchoice = '';
                   2549:     if (selidx >= 0) {
                   2550:         if (numsec[selidx] > 1) {
                   2551:             secok = 0;
                   2552:             var numrolesec = rolesections[selidx].length;
                   2553:             var msgidx = numsec[selidx] - numrolesec;
1.339     raeburn  2554:             secchoice = prompt("$lt{'this'} "+secpick[msgidx]+"\\n$lt{'avai'} "+roleseclist[selidx],"");
1.239     raeburn  2555:             if (secchoice == '') {
                   2556:                 if (msgidx > 0) {
                   2557:                     secok = 1;
                   2558:                 }
                   2559:             } else {
                   2560:                 for (var j=0; j<rolesections[selidx].length; j++) {
                   2561:                     if (rolesections[selidx][j] == secchoice) {
                   2562:                         secok = 1;
                   2563:                     }
                   2564:                 }
                   2565:             }
                   2566:         } else {
                   2567:             if (rolesections[selidx].length == 1) {
                   2568:                 secchoice = rolesections[selidx][0];
                   2569:             }
                   2570:         }
                   2571:     }
                   2572:     if (secok == 1) {
                   2573:         if (secchoice != '') {
                   2574:             fullrole += '/'+secchoice;
                   2575:         }
                   2576:     } else {
                   2577:         if (secchoice != null) {
                   2578:             alert("$lt{'youe'} \\""+secchoice+"\\".\\n $lt{'plst'}");
                   2579:         }
                   2580:         return;
                   2581:     }
                   2582:     if (fullrole == "$env{'request.role'}") {
1.235     raeburn  2583:         return;
                   2584:     }
                   2585:     itemid = retrieveIndex('gotorole');
                   2586:     if (itemid != -1) {
1.239     raeburn  2587:         document.rolechooser.elements[itemid].name = fullrole;
1.235     raeburn  2588:     }
1.401     raeburn  2589:     document.rolechooser.switchrole.value = fullrole;
1.235     raeburn  2590:     document.rolechooser.selectrole.value = '1';
                   2591:     document.rolechooser.submit();
                   2592:     return;
                   2593: }
                   2594: 
                   2595: function retrieveIndex(item) {
                   2596:     for (var i=0;i<document.rolechooser.elements.length;i++) {
                   2597:         if (document.rolechooser.elements[i].name == item) {
                   2598:             return i;
                   2599:         }
                   2600:     }
                   2601:     return -1;
                   2602: }
1.273     droeschl 2603: // ]]>
1.235     raeburn  2604: </script>
                   2605: END
                   2606: }
                   2607: 
1.350     raeburn  2608: sub required_privs {
                   2609:     my $privs =  {
1.457     raeburn  2610:              '/adm/parmset'      => 'opa,vpa',
                   2611:              '/adm/courseprefs'  => 'opa,vpa',
1.350     raeburn  2612:              '/adm/whatsnew'     => 'whn',
1.461     raeburn  2613:              '/adm/populate'     => 'cst,vpa,vcl',
1.350     raeburn  2614:              '/adm/trackstudent' => 'vsa',
1.457     raeburn  2615:              '/adm/statistics'   => 'mgr,vgr',
                   2616:              '/adm/setblock'     => 'dcm,vcb',
1.367     raeburn  2617:              '/adm/coursedocs'   => 'mdc',
1.350     raeburn  2618:            };
                   2619:     unless ($env{'course.'.$env{'request.course.id'}.'.grading'} eq 'spreadsheet') {
1.364     raeburn  2620:         $privs->{'/adm/classcalc'}   = 'vgr',
                   2621:         $privs->{'/adm/assesscalc'}  = 'vgr',
                   2622:         $privs->{'/adm/studentcalc'} = 'vgr';
1.350     raeburn  2623:     }
                   2624:     return $privs;
                   2625: }
1.235     raeburn  2626: 
1.378     raeburn  2627: sub countdown_timer {
                   2628:     if (($env{'request.course.id'}) && ($env{'request.symb'} ne '') &&
1.387     raeburn  2629:         ($env{'request.filename'}=~/$LONCAPA::assess_re/)) {
                   2630:         my ($type,$hastimeleft,$slothastime);
                   2631:         my $now = time;
                   2632:         if ($env{'request.filename'} =~ /\.task$/) {
                   2633:             $type = 'Task';
                   2634:         } else {
                   2635:             $type = 'problem';
                   2636:         }
                   2637:         my ($status,$accessmsg,$slot_name,$slot) =
                   2638:             &Apache::lonhomework::check_slot_access('0',$type);
                   2639:         if ($slot_name ne '') {
                   2640:             if (ref($slot) eq 'HASH') {
                   2641:                 if (($slot->{'starttime'} < $now) &&
                   2642:                     ($slot->{'endtime'} > $now)) {
                   2643:                     $slothastime = 1;
                   2644:                 }
                   2645:             }
                   2646:         }
                   2647:         if ($status ne 'CAN_ANSWER') {
                   2648:             return;
                   2649:         }
1.378     raeburn  2650:         my $duedate = &Apache::lonnet::EXT("resource.0.duedate");
1.380     raeburn  2651:         my @interval=&Apache::lonnet::EXT("resource.0.interval");
1.448     raeburn  2652:         my ($timelimit,$usesdone,$donebuttontext,$proctor,$secret);
1.381     raeburn  2653:         if (@interval > 1) {
1.448     raeburn  2654:             ($timelimit,my $donesuffix) = split(/_/,$interval[0],2);
                   2655:             if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
                   2656:                 $usesdone = 'done';
                   2657:                 $donebuttontext = $1;
                   2658:                 (undef,$proctor,$secret) = split(/_/,$2);
                   2659:             } elsif ($donesuffix =~ /^done(|_.+)$/) {
                   2660:                 $donebuttontext = &mt('Done');
                   2661:                 ($usesdone,$proctor,$secret) = split(/_/,$donesuffix);
                   2662:             }
1.381     raeburn  2663:             my $first_access=&Apache::lonnet::get_first_access($interval[1]);
                   2664:             if ($first_access > 0) {
1.437     raeburn  2665:                 if ($first_access+$timelimit > time) {
1.381     raeburn  2666:                     $hastimeleft = 1;
                   2667:                 }
                   2668:             }
                   2669:         }
1.380     raeburn  2670:         if (($duedate && $duedate > time) ||
1.387     raeburn  2671:             (!$duedate && $hastimeleft) ||
                   2672:             ($slot_name ne '' && $slothastime)) {
1.435     musolffc 2673:             my ($collapse,$expand,$alttxt,$title,$currdisp,$donebutton);
1.387     raeburn  2674:             if ((@interval > 1 && $hastimeleft) ||
                   2675:                 ($type eq 'Task' && $slothastime)) {
1.378     raeburn  2676:                 $currdisp = 'inline';
                   2677:                 $collapse = '&#9658;&nbsp;';
1.435     musolffc 2678:                 if ((@interval > 1) && ($hastimeleft)) {
1.437     raeburn  2679:                     if ($usesdone eq 'done') {
1.448     raeburn  2680:                         $donebutton = &done_button_js($interval[1],'','',$proctor,$donebuttontext);
1.437     raeburn  2681:                     }
1.435     musolffc 2682:                 }
1.378     raeburn  2683:             } else {
                   2684:                 $currdisp = 'none';
                   2685:                 $expand = '&#9668;&nbsp;';
                   2686:             }
                   2687:             unless ($env{'environment.icons'} eq 'iconsonly') {
1.379     raeburn  2688:                 $alttxt = &mt('Timer');
                   2689:                 $title = $alttxt.'&nbsp;';
1.378     raeburn  2690:             }
                   2691:             my $desc = &mt('Countdown to due date/time');
1.435     musolffc 2692: 
1.378     raeburn  2693:             return <<END;
1.435     musolffc 2694: $donebutton
1.378     raeburn  2695: <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
                   2696: <span id="ddcountcollapse" class="LC_menubuttons_inline_text">
                   2697: $collapse
1.379     raeburn  2698: </span></a>
1.378     raeburn  2699: <span id="duedatecountdown" class="LC_menubuttons_inline_text" style="display: $currdisp;"></span>
                   2700: <a href="javascript:toggleCountdown();" class="LC_menubuttons_link">
                   2701: <span id="ddcountexpand" class="LC_menubuttons_inline_text" >$expand</span>
1.379     raeburn  2702: <img src="/res/adm/pages/timer.png" title="$desc" class="LC_icon" alt="$alttxt" /><span class="LC_menubuttons_inline_text">$title</span></a>
1.378     raeburn  2703: END
                   2704:         }
                   2705:     }
                   2706:     return;
                   2707: }
                   2708: 
1.445     raeburn  2709: sub placement_progress {
                   2710:     my ($totalpoints,$incomplete) = &Apache::lonplacementtest::check_completion(undef,undef,1);
                   2711:     my $complete = 100 - $incomplete;
                   2712:     return '<span class="LC_placement_prog">'.
                   2713:            &mt('Test is [_1]% complete',$complete).'</span>';
                   2714: }
                   2715: 
1.2       www      2716: # ================================================================ Main Program
                   2717: 
1.16      harris41 2718: BEGIN {
1.166     albertel 2719:     if (! defined($readdesk)) {
1.283     droeschl 2720:         {
                   2721:             my $tabfile = $Apache::lonnet::perlvar{'lonTabDir'}.'/mydesk.tab';
                   2722:             if ( CORE::open( my $config,"<$tabfile") ) {
                   2723:                 while (my $configline=<$config>) {
                   2724:                     $configline=(split(/\#/,$configline))[0];
                   2725:                     $configline=~s/^\s+//;
                   2726:                     chomp($configline);
1.209     www      2727:                     if ($configline=~/^cat\:/) {
1.283     droeschl 2728:                         my @entries=split(/\:/,$configline);
                   2729:                         $category_positions{$entries[2]}=$entries[1];
                   2730:                         $category_names{$entries[2]}=$entries[3];
                   2731:                     } elsif ($configline=~/^prim\:/) {
1.415     raeburn  2732:                         my @entries = (split(/\:/, $configline))[1..6];
1.400     raeburn  2733:                         push(@primary_menu,\@entries);
1.371     raeburn  2734:                     } elsif ($configline=~/^primsub\:/) {
                   2735:                         my ($parent,@entries) = (split(/\:/, $configline))[1..4];
1.400     raeburn  2736:                         push(@{$primary_submenu{$parent}},\@entries);
1.283     droeschl 2737:                     } elsif ($configline=~/^scnd\:/) {
                   2738:                         my @entries = (split(/\:/, $configline))[1..5];
1.401     raeburn  2739:                         push(@secondary_menu,\@entries);
1.283     droeschl 2740:                     } elsif ($configline) {
                   2741:                         push(@desklines,$configline);
                   2742:                     }
                   2743:                 }
                   2744:                 CORE::close($config);
                   2745:             }
                   2746:         }
                   2747:         $readdesk='done';
1.2       www      2748:     }
                   2749: }
1.30      www      2750: 
1.1       www      2751: 1;
                   2752: __END__
                   2753: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.