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