--- loncom/interface/lonmenu.pm 2024/02/28 19:08:32 1.369.2.83.2.18 +++ loncom/interface/lonmenu.pm 2024/08/22 02:11:11 1.369.2.83.2.19 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines to control the menu # -# $Id: lonmenu.pm,v 1.369.2.83.2.18 2024/02/28 19:08:32 raeburn Exp $ +# $Id: lonmenu.pm,v 1.369.2.83.2.19 2024/08/22 02:11:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -456,10 +456,10 @@ sub primary_menu { # #TODO this should probably be moved somewhere more central #since it can be used by different parts of the system -sub getauthor{ +sub getauthor { return unless $env{'request.role'}=~/^(ca|aa|au)/; #nothing to do if user isn't some kind of author - #co- or assistent author? + #co- or assistant author? my ($dom, $user) = ($env{'request.role'} =~ /^(?:ca|aa)\.\/($match_domain)\/($match_username)$/) ? ($1, $2) #domain, username of the parent author : @env{ ('request.role.domain', 'user.name') }; #own domain, username @@ -500,6 +500,15 @@ sub secondary_menu { my $canplc = &Apache::lonnet::allowed('plc', $crs_sec); my $author = &getauthor(); + my ($is_author,$is_coauthor); + if ($author) { + if ($env{'request.role'} =~ /^au\./) { + $is_author = 1; + } elsif ($env{'request.role'} =~ /^ca\./) { + $is_coauthor = 1; + } + } + my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv,$grouptools, $lti,$ltimapres,%ltiexc,%menuopts); $grouptools = 0; @@ -559,13 +568,24 @@ sub secondary_menu { $linkattr = 'aria-disabled="true"'; } - my ($canmodifycoauthor); + my ($canlistcoauthors,$canmodifycoauthor); if ($env{'request.role'} eq "au./$env{'user.domain'}/") { my $extent = "$env{'user.domain'}/$env{'user.name'}"; if ((&Apache::lonnet::allowed('cca',$extent)) || (&Apache::lonnet::allowed('caa',$extent))) { $canmodifycoauthor = 1; } + } elsif ($env{'request.role'} =~ m{^(aa|ca)\./($match_domain/$match_username)$}) { + my ($role,$extent) = ($1,$2); + if (&Apache::lonnet::allowed('vca',$extent)) { + if ($env{"environment.internal.manager./$extent"}) { + $canmodifycoauthor = 1; + } else { + $canlistcoauthors = 1; + } + } elsif (&Apache::lonnet::allowed('vaa',$extent)) { + $canlistcoauthors = 1; + } } my ($roleswitcher_js,$roleswitcher_form); @@ -590,7 +610,11 @@ sub secondary_menu { # evaluate conditions next if ref($menuitem) ne 'ARRAY'; next if $$menuitem[4] ne 'always' - && ($$menuitem[4] ne 'author' && $$menuitem[4] ne 'cca') + && $$menuitem[4] ne 'coauthor' + && $$menuitem[4] ne 'author' + && $$menuitem[4] ne 'authorspace' + && $$menuitem[4] ne 'vca' + && $$menuitem[4] ne 'mca' && !$env{'request.course.id'}; next if $$menuitem[4] =~ /^crsedit/ && (!$canedit && !$canvieweditor); @@ -622,9 +646,17 @@ sub secondary_menu { && !$showfeeds; next if $$menuitem[4] eq 'plc' && !$canplc; - next if $$menuitem[4] eq 'author' + next if $$menuitem[4] eq 'authorspace' && !$author; - next if $$menuitem[4] eq 'cca' + next if $$menuitem[4] eq 'author' + && !$is_author; + next if $$menuitem[4] eq 'coauthor' + && !$is_coauthor; + next if $$menuitem[4] eq 'vca' + && (!$canlistcoauthors || $canmodifycoauthor); + next if $$menuitem[4] eq 'vaa' + && (!$canlistcoauthors || $canmodifycoauthor); + next if $$menuitem[4] eq 'mca' && !$canmodifycoauthor; next if $$menuitem[4] eq 'notltimapres' && $ltimapres; @@ -662,8 +694,8 @@ sub secondary_menu { next if ($item->[2] eq 'vcg' && !$canviewgrps); next if ($item->[2] eq 'crsedit' && !$canedit && !$canvieweditor); next if ($item->[2] eq 'params' && !$canmodpara && !$canviewpara); - next if ($item->[2] eq 'author' && !$author); - next if ($item->[2] eq 'cca' && !$canmodifycoauthor); + next if ($item->[2] eq 'author' && !$is_author); + next if ($item->[2] eq 'vca' && !$canlistcoauthors); next if ($item->[2] eq 'lti' && !$lti); if ($item->[2] =~ /^lti(portfolio|wishlist|blog)$/) { my $tool = $1; @@ -746,6 +778,20 @@ sub secondary_menu { } $menu =~ s/\[url\]/$escurl/g; $menu =~ s/\[symb\]/$escsymb/g; + } elsif (($menu =~ m{/adm/preferences\?}) && ($menu =~ /\[returnurl\]/)) { + my $returnurl = $ENV{'REQUEST_URI'}; + if ($ENV{'REQUEST_URI'} =~ m{/adm/preferences\?action=authorsettings\&returnurl=([^\&]+)$}) { + $returnurl = $1; + } + if (($returnurl =~ m{^/adm/createuser($|\?action=)}) || + ($returnurl =~ m{^/priv/$match_domain/$match_username}) || + ($returnurl =~ m{^/res(/?$|/$match_domain/$match_username)})) { + $returnurl =~ s{\?.*$}{}; + $returnurl = '&returnurl='.&HTML::Entities::encode($returnurl,'"<>&\''); + } else { + undef($returnurl); + } + $menu =~ s/\[returnurl\]/$returnurl/; } $menu =~ s/\[uname\]/$$author{user}/g; $menu =~ s/\[udom\]/$$author{dom}/g; @@ -898,7 +944,7 @@ sub innerregister { my ($forcereg,$bread_crumbs,$group,$pagebuttonshide,$hostname, $ltiscope,$ltiuri,$showncrumbsref) = @_; my $const_space = ($env{'request.state'} eq 'construct'); - my $is_const_dir = 0; + my $in_daxe = 0; if ($env{'request.noversionuri'} =~ m{^/res/adm/pages/}) { return ''; } @@ -1246,7 +1292,7 @@ END # End course context # Prepare the rest of the buttons - my ($menuitems,$got_prt,$got_wishlist,$cstritems); + my ($menuitems,$got_prt,$got_wishlist,$cstritems,$toplevel_cstr); if ($const_space) { # # We are in construction space @@ -1257,14 +1303,32 @@ END ($env{'request.filename'}=~m{^\Q$londocroot/priv/\E([^/]+)/([^/]+)/(.*)$}); my $currdir = '/priv/'.$udom.'/'.$uname.'/'.$thisdisfn; if ($currdir =~ m-/$-) { - $is_const_dir = 1; if ($thisdisfn eq '') { - $is_const_dir = 2; + $toplevel_cstr = 1; + } + my $esc_currdir = &Apache::loncommon::escape_single($currdir); + $menuitems=(<<ENDMENUITEMS); +s&6&3&pub.png&Publish&dir[_2]&gocstr('/adm/publish','$esc_currdir')&Publish this Directory +s&7&4&docs-22x22.png&Edit Metadata&defaults[_1]&gopost('${esc_currdir}default.meta','')&Edit metadata for this Directory +s&7&2&prt.png&Print&printout[_1]&gocstr('/adm/printout','$esc_currdir')&Print contents of directory +s&7&1&del.png&Delete&dir[_3]&gocstr('/adm/cfile?action=delete','$esc_currdir')&Delete this Directory +ENDMENUITEMS + if ($env{'environment.canarchive'}) { + $menuitems .= (<<ENDMENUITEMS); +s&7&7&archive.png&Export&dir[_1]&gocstr('/adm/cfile?action=archive','$esc_currdir')&Export Authoring Space Archive +ENDMENUITEMS } } else { $currdir =~ s|[^/]+$||; my $cleandisfn = &Apache::loncommon::escape_single($thisdisfn); my $esc_currdir = &Apache::loncommon::escape_single($currdir); + my $pubfile = "/res/$udom/$uname/$thisdisfn"; + my $candelete = 1; + if (-e $londocroot.$pubfile) { + unless (&Apache::lonnet::metadata($pubfile,'obsolete')) { + undef($candelete); + } + } # # Probably should be in mydesk.tab # @@ -1272,8 +1336,17 @@ END s&6&1&list.png&Directory&dir[_1]&golist('$esc_currdir')&List current directory s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/priv/$udom/$uname/$cleandisfn')&Retrieve old version s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/priv/$udom/$uname/$cleandisfn')&Publish this resource +s&7&3©.png&Copy&resource[_4]&gocstr('/adm/cfile?action=copy','/priv/$udom/$uname/$cleandisfn')&Copy this resource +ENDMENUITEMS +# +# Rename and Delete only available if obsolete or unpublished +# + if ($candelete) { + $menuitems .= (<<ENDMENUITEMS); +s&7&4&rename.png&Rename&resource[_5]&gocstr('/adm/cfile?action=rename','/priv/$udom/$uname/$cleandisfn')&Rename this resource s&7&1&del.png&Delete&resource[_2]&gocstr('/adm/cfile?action=delete','/priv/$udom/$uname/$cleandisfn')&Delete this resource ENDMENUITEMS + } # # Print only makes sense for certain mime types @@ -1287,7 +1360,36 @@ ENDMENUITEMS $cstritems = $menuitems; undef($menuitems); } +# +# "Exit Daxe" in Functions menu when using Daxe +# + if ((($env{'form.editmode'} eq 'daxe') && + ($thisdisfn=~/\.(xml|html|htm|xhtml|xhtm)$/)) || + (($env{'form.problemmode'} eq 'daxe') && + ($thisdisfn=~/$LONCAPA::assess_re/))) { + my %editors = &Apache::loncommon::permitted_editors(); + if ($editors{'daxe'}) { + my $privfile = &Apache::loncommon::escape_single("/priv/$udom/$uname/$thisdisfn"); + $in_daxe = 1; + $menuitems .= (<<ENDMENUITEMS); +my $privfile = &Apache::loncommon::escape_single("/priv/$udom/$uname/$thisdisfn"); +s&7&6&tolastloc.png&Exit Daxe&resource[_1]&go('$privfile')&Exit editing this resource +ENDMENUITEMS + } + } + } +# +# Editing options usually accessed via "Settings" in inline menu need to be +# accessed in a different way, when Authoring Space is accessed in course +# context +# + if ($env{'request.role'} !~/^(aa|ca|au)/) { + my $privfile = &Apache::loncommon::escape_single("/priv/$udom/$uname/$thisdisfn"); + $menuitems .= (<<ENDMENUITEMS); +s&7&5&editops.png&Options&edit[_1]&gocstr('/adm/preferences?action=authorsettings','$privfile')&Authoring Space Options +ENDMENUITEMS } + if (ref($bread_crumbs) eq 'ARRAY') { &Apache::lonhtmlcommon::clear_breadcrumbs(); foreach my $crumb (@{$bread_crumbs}){ @@ -1477,8 +1579,13 @@ ENDMENUITEMS &Apache::lonhtmlcommon::add_breadcrumb_tool( 'tools',@tools); + #exit editing link/icon when using daxe in construction space #publish button in construction space if ($env{'request.state'} eq 'construct'){ + if ($in_daxe) { + &Apache::lonhtmlcommon::add_breadcrumb_tool( + 'advtools', $inlineremote[76]); + } &Apache::lonhtmlcommon::add_breadcrumb_tool( 'advtools', $inlineremote[63]); } else { @@ -1486,6 +1593,12 @@ ENDMENUITEMS 'tools', $inlineremote[63]); } &advtools_crumbs(@inlineremote); + #options link/icon in constructions space viewed with course role + if (($env{'request.state'} eq 'construct') && + ($env{'request.role'} !~/^(aa|ca|au)/)) { + &Apache::lonhtmlcommon::add_breadcrumb_tool( + 'advtools', $inlineremote[75]); + } } } else { if ($linkprotout) { @@ -1493,7 +1606,7 @@ ENDMENUITEMS } } my ($topic_help,$topic_help_text); - if ($is_const_dir == 2) { + if ($toplevel_cstr) { if ((($ENV{'SERVER_PORT'} == 443) || ($Apache::lonnet::protocol{$Apache::lonnet::perlvar{'lonHostID'}} eq 'https')) && (&Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'},'webdav'))) { @@ -1910,20 +2023,40 @@ sub prepare_functions { $editbutton = &get_editbutton($cfile,$home,$switchserver, $forceedit,$forceview,$forcereg); } - } elsif ((!$env{'request.course.id'}) && - ($env{'user.author'}) && ($env{'request.filename'}) && - ($env{'request.role'} !~/^(aa|ca|au)/)) { + } elsif (!$env{'request.course.id'}) { + if (($env{'user.author'}) && ($resurl eq '/adm/viewcoauthors')) { + if ($env{'request.role'} =~/^(ca|au)/) { + my ($audom,$auname); + if ($env{'request.role'} eq "au./$env{'user.domain'}/") { + ($audom,$auname) = ($env{'user.domain'},$env{'user.name'}); + } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)}) { + ($audom,$auname) = ($1,$2); + } + if (($audom ne '') && ($auname ne '')) { + my $file=&Apache::lonnet::declutter($env{'request.filename'}); + ($cfile,$home,$switchserver,$forceedit,$forceview) = + &Apache::lonnet::can_edit_resource($file,$auname,$audom, + $resurl); + if ($cfile) { + $editbutton = &get_editbutton($resurl,'','',$forceedit, + $forceview); + } + } + } + } elsif (($env{'user.author'}) && ($env{'request.filename'}) && + ($env{'request.role'} !~/^(aa|ca|au)/)) { # # Currently do not have the role of author or co-author. # Do we have authoring privileges for the resource? # - my $file=&Apache::lonnet::declutter($env{'request.filename'}); - ($cfile,$home,$switchserver,$forceedit,$forceview) = - &Apache::lonnet::can_edit_resource($file,$cnum,$cdom, - &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group); - if (($cfile) && ($home ne '') && ($home ne 'no_host')) { - $editbutton = &get_editbutton($cfile,$home,$switchserver, - $forceedit,$forceview,$forcereg); + my $file=&Apache::lonnet::declutter($env{'request.filename'}); + ($cfile,$home,$switchserver,$forceedit,$forceview) = + &Apache::lonnet::can_edit_resource($file,$cnum,$cdom, + &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group); + if (($cfile) && ($home ne '') && ($home ne 'no_host')) { + $editbutton = &get_editbutton($cfile,$home,$switchserver, + $forceedit,$forceview,$forcereg); + } } } elsif ($env{'request.course.id'}) { # @@ -1975,7 +2108,14 @@ sub prepare_functions { } elsif (($resurl !~ m{^/?adm/($match_domain)/($match_username)/aboutme$}) && ($resurl ne '/cgi-bin/printout.pl')) { if ($env{'request.filename'}) { - my $file=&Apache::lonnet::declutter($env{'request.filename'}); + my $file; + my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'}; + if ($env{'request.filename'} =~ m{^\Q$londocroot\E/priv/}) { + $file = $env{'request.filename'}; + $file =~ s{^\Q$londocroot\E/}{}; + } else { + $file=&Apache::lonnet::declutter($env{'request.filename'}); + } ($cfile,$home,$switchserver,$forceedit,$forceview) = &Apache::lonnet::can_edit_resource($file,$cnum,$cdom, &Apache::lonnet::clutter($resurl),$env{'request.symb'},$group); @@ -2118,8 +2258,13 @@ sub advtools_crumbs { &Apache::lonhtmlcommon::add_breadcrumb_tool( 'advtools', @funcs[61,64,65,66,67,74]); } elsif ($env{'request.noversionuri'} !~ m{^/adm/(navmaps|viewclasslist)(\?|$)}) { - &Apache::lonhtmlcommon::add_breadcrumb_tool( - 'advtools', @funcs[61,71,72,73,74,75,92]); + if ($env{'request.state'} eq 'construct') { + &Apache::lonhtmlcommon::add_breadcrumb_tool( + 'advtools', @funcs[61,73,74,71,72,77]); + } else { + &Apache::lonhtmlcommon::add_breadcrumb_tool( + 'advtools', @funcs[61,71,72,73,74,75,92]); + } } elsif ($env{'request.noversionuri'} eq '/adm/viewclasslist') { &Apache::lonhtmlcommon::add_breadcrumb_tool( 'advtools', $funcs[61]); @@ -2365,6 +2510,8 @@ sub rawconfig { } else { next; } + } elsif ($priv eq 'cca') { + next if ($rol eq 'cm'); } if ((($priv eq 'bre') && (&Apache::lonnet::allowed($priv,$prt) eq 'F')) || (($priv ne 'bre') && (&Apache::lonnet::allowed($priv,$prt)))) { @@ -2446,6 +2593,24 @@ sub rawconfig { } } } + } elsif ($pro eq 'coauthor') { + if ($env{'request.role'}=~ m{^(ca|aa)\./($match_domain)/($match_username)$}) { + my ($role,$audom,$auname) = ($1,$2,$3); + if ((($prt eq 'raa') && ($role eq 'aa')) || + (($prt eq 'rca') && ($role eq 'ca') && + (!$env{"environment.internal.manager./$audom/$auname"}))) { + $output.=&switch($auname,$audom, + $row,$col,$img,$top,$bot,$act,$desc,$cat); + } + } + } elsif ($pro eq 'coauthorenv_manager') { + if ($env{'request.role'}=~ m{^ca\./($match_domain)/($match_username)$}) { + my ($audom,$auname) = ($1,$2); + if ($env{"environment.internal.manager./$audom/$auname"}) { + $output.=&switch($auname,$audom, + $row,$col,$img,$top,$bot,$act,$desc,$cat); + } + } } elsif ($pro eq 'tools') { my @tools = ('aboutme','blog','portfolio'); if (grep(/^\Q$prt\E$/,@tools)) { @@ -2931,6 +3096,8 @@ sub utilityfunctions { my $esc_url=&escape($currenturl); my $esc_symb=&escape($currentsymb); + my $newname = &mt('New Name'); + &js_escape(\$newname); my $countdown = &countdown_toggle_js(); @@ -3022,6 +3189,22 @@ function gocstr(url,filename) { this.document.cstrdelete.submit(); return; } + if ((url == '/adm/cfile?action=copy') || (url == '/adm/cfile?action=rename')) { + this.document.cstrcopy.filename.value = filename; + var oldname = filename.substring(filename.lastIndexOf("/") + 1); + var newname=prompt('$newname',oldname); + if (newname == "" || !newname || newname == oldname) { + return; + } + if (url == '/adm/cfile?action=rename') { + this.document.cstrcopy.action.value = 'rename'; + } else { + this.document.cstrcopy.action.value = 'copy'; + } + this.document.cstrcopy.newfilename.value = newname; + this.document.cstrcopy.submit(); + return; + } if (url == '/adm/printout') { this.document.cstrprint.postdata.value = filename this.document.cstrprint.curseed.value = 0; @@ -3048,6 +3231,10 @@ function gocstr(url,filename) { this.document.cstrprint.submit(); return; } + if (url == '/adm/preferences?action=authorsettings') { + document.location.href=url+'&returnurl='+filename; + return; + } if (url !='') { this.document.constspace.filename.value = filename; this.document.constspace.action = url; @@ -3199,6 +3386,11 @@ sub constspaceform { <input type="hidden" name="curseed" value="" /> <input type="hidden" name="problemtype" value="" /> </form> +<form name="cstrcopy" action="/adm/cfile" method="post"$target> +<input type="hidden" name="action" value="copy" /> +<input type="hidden" name="filename" value="" /> +<input type="hidden" name="newfilename" value="" /> +</form> ENDCONSTSPACEFORM }