--- loncom/interface/londocs.pm 2016/10/31 19:48:59 1.610 +++ loncom/interface/londocs.pm 2023/07/11 12:44:18 1.700 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.610 2016/10/31 19:48:59 raeburn Exp $ +# $Id: londocs.pm,v 1.700 2023/07/11 12:44:18 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -45,6 +45,7 @@ use Apache::lontemplate(); use Apache::lonsimplepage(); use Apache::lonhomework(); use Apache::lonpublisher(); +use Apache::loncourserespicker(); use HTML::Entities; use HTML::TokeParser; use GDBM_File; @@ -52,6 +53,7 @@ use File::MMagic; use File::Copy; use Apache::lonlocal; use Cwd; +use UUID::Tiny ':std'; use LONCAPA qw(:DEFAULT :match); my $iconpath; @@ -88,7 +90,7 @@ sub storemap { if ($map =~ /^default/) { $hadchanges=1; - } else { + } elsif ($contentchg) { $suppchanges=1; } return ($errtext,0); @@ -142,7 +144,101 @@ sub clean { return $title; } +sub default_folderpath { + my ($coursenum,$coursedom,$navmapref) = @_; + return unless ($coursenum && $coursedom && ref($navmapref)); +# Check if entire course is hidden and/or encrypted + my ($hiddenmap,$encryptmap,$folderpath,$hiddentop); + my $toplevel = "uploaded/$coursedom/$coursenum/default.sequence"; + unless (ref($$navmapref)) { + $$navmapref = Apache::lonnavmaps::navmap->new(); + } + if (ref($$navmapref)) { + if (lc($$navmapref->get_mapparam(undef,$toplevel,"0.hiddenresource")) eq 'yes') { + my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) }; + my @resources = $$navmapref->retrieveResources($toplevel,$filterFunc,1,1); + unless (@resources) { + $hiddenmap = 1; + unless ($env{'request.role.adv'}) { + $hiddentop = 1; + if ($env{'form.folder'}) { + undef($env{'form.folder'}); + } + } + } + } + if (lc($$navmapref->get_mapparam(undef,$toplevel,"0.encrypturl")) eq 'yes') { + $encryptmap = 1; + } + } + unless ($hiddentop) { + $folderpath='default&'.&escape(&mt('Main Content')). + '::'.$hiddenmap.':'.$encryptmap.'::'; + } + if (wantarray) { + return ($folderpath,$hiddentop); + } else { + return $folderpath; + } +} +sub validate_supppath { + my ($coursenum,$coursedom) = @_; + my $backto; + if ($env{'form.supppath'} ne '') { + my @items = split(/\&/,$env{'form.supppath'}); + my ($badpath,$got_supp,$supppath,%supphidden,%suppids); + for (my $i=0; $i<@items; $i++) { + my $odd = $i%2; + if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) { + $badpath = 1; + last; + } elsif ($odd) { + my $suffix; + my $idx = $i-1; + if ($items[$i] =~ /^([^:]*)::(|1):::$/) { + $backto .= '&'.$1; + } elsif ($items[$idx] eq 'supplemental') { + $backto .= '&'.$items[$i]; + } else { + $backto .= '&'.$items[$i]; + my $is_hidden; + unless ($got_supp) { + my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom); + if (ref($supplemental) eq 'HASH') { + if (ref($supplemental->{'hidden'}) eq 'HASH') { + %supphidden = %{$supplemental->{'hidden'}}; + } + if (ref($supplemental->{'ids'}) eq 'HASH') { + %suppids = %{$supplemental->{'ids'}}; + } + } + $got_supp = 1; + } + if (ref($suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}) eq 'ARRAY') { + my $mapid = $suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}->[0]; + if ($supphidden{$mapid}) { + $is_hidden = 1; + } + } + $suffix = '::'.$is_hidden.':::'; + } + $supppath .= '&'.$items[$i].$suffix; + } else { + $supppath .= '&'.$items[$i]; + $backto .= '&'.$items[$i]; + } + } + if ($badpath) { + delete($env{'form.supppath'}); + } else { + $supppath =~ s/^\&//; + $backto =~ s/^\&//; + $env{'form.supppath'} = $supppath; + } + } + return $backto; +} sub dumpcourse { my ($r) = @_; @@ -567,9 +663,9 @@ sub recurse_html { } else { $relfile = $dependency; $depurl = $currurlpath; - $depurl =~ s{[^/]+$}{}; + $depurl =~ s{[^/]+$}{}; $depurl .= $dependency; - ($newcontainer) = ($depurl =~ m{^\Q$prefix\E(.+)$}); + ($newcontainer) = ($depurl =~ m{^\Q$prefix\E(.+)$}); } next if ($relfile eq ''); my $newname = $replacehash->{$container}; @@ -618,11 +714,12 @@ sub group_import { } } if ($url) { - if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/exttool)s?\:?(.*)$}) { + if ($url =~ m{^(/adm/$coursedom/$coursenum/(\d+)/ext\.tool)\:?(.*)$}) { $url = $1; my $marker = $2; my $info = $3; - my ($toolid,%toolhash,%toolsettings); + my ($toolid,$toolprefix,$tooltype,%toolhash,%toolsettings); + my @extras = ('linktext','explanation','crslabel','crstitle','crsappend'); my @toolinfo = split(/:/,$info); if ($residx) { %toolsettings=&Apache::lonnet::dump('exttool_'.$marker,$coursedom,$coursenum); @@ -630,73 +727,149 @@ sub group_import { } else { $toolid = shift(@toolinfo); } + if ($toolid =~ /^c/) { + $tooltype = 'crs'; + $toolprefix = 'c'; + } else { + $tooltype = 'dom'; + } $toolid =~ s/\D//g; ($toolhash{'target'},$toolhash{'width'},$toolhash{'height'}, - $toolhash{'crslabel'},$toolhash{'crstitle'}) = @toolinfo; - $toolhash{'crslabel'} = &unescape($toolhash{'crslabel'}); - $toolhash{'crstitle'} = &unescape($toolhash{'crstitle'}); + $toolhash{'linktext'},$toolhash{'explanation'},$toolhash{'crslabel'}, + $toolhash{'crstitle'},$toolhash{'crsappend'},$toolhash{'gradable'}) = @toolinfo; + foreach my $item (@extras) { + $toolhash{$item} = &unescape($toolhash{$item}); + } + if ($folder =~ /^supplemental/) { + delete($toolhash{'gradable'}); + } else { + $toolhash{'gradable'} =~ s/\D+//g; + } if (ref($ltitoolsref) eq 'HASH') { - my @deleted; - if (ref($ltitoolsref->{$toolid}) eq 'HASH') { - if ($ltitoolsref->{$toolid}->{'url'} =~ m{^https://}) { - $url =~ s/exttool$/exttools/; - } - $toolhash{'id'} = $toolid; - if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'window')) { - if ($toolhash{'target'} eq 'window') { - foreach my $item ('width','height') { - $toolhash{$item} =~ s/^\s+//; - $toolhash{$item} =~ s/\s+$//; + if (ref($ltitoolsref->{$tooltype}) eq 'HASH') { + if (ref($ltitoolsref->{$tooltype}->{$toolid}) eq 'HASH') { + my %tools = %{$ltitoolsref->{$tooltype}->{$toolid}}; + my @deleted; + $toolhash{'id'} = $toolprefix.$toolid; + if (($toolhash{'target'} eq 'iframe') || ($toolhash{'target'} eq 'tab') || + ($toolhash{'target'} eq 'window')) { + if ($toolhash{'target'} eq 'window') { + foreach my $item ('width','height') { + $toolhash{$item} =~ s/^\s+//; + $toolhash{$item} =~ s/\s+$//; + if ($toolhash{$item} =~ /\D/) { + delete($toolhash{$item}); + if ($residx) { + if ($toolsettings{$item}) { + push(@deleted,$item); + } + } + } + } + } + } elsif ($residx) { + $toolhash{'target'} = $toolsettings{'target'}; + if ($toolhash{'target'} eq 'window') { + foreach my $item ('width','height') { + $toolhash{$item} = $toolsettings{$item}; + } + } + } elsif (ref($tools{'display'}) eq 'HASH') { + $toolhash{'target'} = $tools{'display'}{'target'}; + if ($toolhash{'target'} eq 'window') { + $toolhash{'width'} = $tools{'display'}{'width'}; + $toolhash{'height'} = $tools{'display'}{'height'}; } } - } elsif ($residx) { - $toolhash{'target'} = $toolsettings{'target'}; - if ($toolhash{'target'} eq 'window') { - $toolhash{'width'} = $toolsettings{'width'}; - $toolhash{'height'} = $toolsettings{'height'}; - } - } elsif (ref($ltitoolsref->{$toolid}->{'display'}) eq 'HASH') { - $toolhash{'target'} = $ltitoolsref->{$toolid}->{'display'}->{'target'}; - if ($toolhash{'target'} eq 'window') { - $toolhash{'width'} = $ltitoolsref->{$toolid}->{'display'}->{'width'}; - $toolhash{'height'} = $ltitoolsref->{$toolid}->{'display'}->{'height'}; - } - } - if ($toolhash{'target'} eq 'iframe') { - delete($toolhash{'width'}); - delete($toolhash{'height'}); - if ($residx) { - if ($toolsettings{'width'}) { - push(@deleted,'width'); + if ($toolhash{'target'} eq 'iframe') { + foreach my $item ('width','height','linktext','explanation') { + delete($toolhash{$item}); + if ($residx) { + if ($toolsettings{$item}) { + push(@deleted,$item); + } + } } - if ($toolsettings{'height'}) { - push(@deleted,'height'); + } elsif ($toolhash{'target'} eq 'tab') { + foreach my $item ('width','height') { + delete($toolhash{$item}); + if ($residx) { + if ($toolsettings{$item}) { + push(@deleted,$item); + } + } } } - } - if (ref($ltitoolsref->{$toolid}->{'crsconf'}) eq 'HASH') { - foreach my $item ('label','title') { - if ($ltitoolsref->{$toolid}->{'crsconf'}->{$item}) { - $toolhash{'crs'.$item} =~ s/^\s+//; - $toolhash{'crs'.$item} =~ s/\s+$//; - if ($toolhash{'crs'.$item} eq '') { - delete($toolhash{'crs'.$item}); + if (ref($tools{'crsconf'}) eq 'HASH') { + foreach my $item ('label','title','linktext','explanation') { + my $crsitem; + if (($item eq 'label') || ($item eq 'title')) { + $crsitem = 'crs'.$item; + } else { + $crsitem = $item; } - } else { - delete($toolhash{'crs'.$item}); + if ($tools{'crsconf'}{$item}) { + $toolhash{$crsitem} =~ s/^\s+//; + $toolhash{$crsitem} =~ s/\s+$//; + if ($toolhash{$crsitem} eq '') { + delete($toolhash{$crsitem}); + } + } else { + delete($toolhash{$crsitem}); + } + if (($residx) && (exists($toolsettings{$crsitem}))) { + unless (exists($toolhash{$crsitem})) { + push(@deleted,$crsitem); + } + } + } + } + if ($toolhash{'passback'}) { + my $gradesecret = UUID::Tiny::create_uuid_as_string(UUID_V4); + $toolhash{'gradesecret'} = $gradesecret; + $toolhash{'gradesecretdate'} = time; + } + if ($toolhash{'roster'}) { + my $rostersecret = UUID::Tiny::create_uuid_as_string(UUID_V4); + $toolhash{'rostersecret'} = $rostersecret; + $toolhash{'rostersecretdate'} = time; + } + my $changegradable; + if (($residx) && ($folder =~ /^default/)) { + if ($toolsettings{'gradable'}) { + unless (($toolhash{'gradable'}) || (defined($LONCAPA::map::zombies[$residx]))) { + push(@deleted,'gradable'); + $changegradable = 1; + } + } elsif ($toolhash{'gradable'}) { + $changegradable = 1; } - if (($residx) && (exists($toolsettings{'crs'.$item}))) { - unless (exists($toolhash{'crs'.$item})) { - push(@deleted,'crs'.$item); + if (($caller eq 'londocs') && (defined($LONCAPA::map::zombies[$residx]))) { + $changegradable = 1; + if ($toolsettings{'gradable'}) { + $toolhash{'gradable'} = 1; } } } - } - my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum); - if ($putres eq 'ok') { - if (@deleted) { - &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum); - } + my $putres = &Apache::lonnet::put('exttool_'.$marker,\%toolhash,$coursedom,$coursenum); + if ($putres eq 'ok') { + if (@deleted) { + &Apache::lonnet::del('exttool_'.$marker,\@deleted,$coursedom,$coursenum); + } + if (($changegradable) && ($folder =~ /^default/)) { + my $val; + if ($toolhash{'gradable'}) { + $val = 'yes'; + } else { + $val = 'no'; + } + &LONCAPA::map::storeparameter($residx,'parameter_0_gradable',$val, + 'string_yesno'); + &remember_parms($residx,'gradable','set',$val); + } + } else { + return (&mt('Failed to save update to external tool.'),1); + } } } } @@ -712,8 +885,8 @@ sub group_import { $donechk = 1; } if ($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) { - &contained_map_check($url,$folder,\%removefrommap,\%removeparam, - \%addedmaps,\%hierarchy,\%titles,$allmaps); + &contained_map_check($url,$folder,$coursenum,$coursedom,\%removefrommap, + \%removeparam,\%addedmaps,\%hierarchy,\%titles,$allmaps); $importuploaded = 1; } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) { next if ($allmaps->{$url}); @@ -726,26 +899,27 @@ sub group_import { } my $ext = 'false'; if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } - $name = &LONCAPA::map::qtunescape($name); - if ($name eq '') { - $name = &LONCAPA::map::qtunescape(&mt('Web Page')); - } if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) { my $filepath = $1; - my $fname = $name; - if ($fname =~ /^\W+$/) { + my $fname; + if ($name eq '') { + $name = &mt('Web Page'); $fname = 'web'; } else { - $fname =~ s/\W/_/g; - } - if (length($fname) > 15) { - $fname = substr($fname,0,14); + $fname = $name; + $fname=&Apache::lonnet::clean_filename($fname); + if ($fname eq '') { + $fname = 'web'; + } elsif (length($fname) > 15) { + $fname = substr($fname,0,14); + } } + my $title = &Apache::loncommon::cleanup_html($name); my $initialtext = &mt('Replace with your own content.'); my $newhtml = < -$name +$title $initialtext @@ -753,7 +927,7 @@ $initialtext END $env{'form.output'}=$newhtml; - my $result = + my $result = &Apache::lonnet::finishuserfileupload($coursenum,$coursedom, 'output', "$filepath/$residx/$fname.html"); @@ -767,6 +941,7 @@ END return (&mt('Failed to save new web page.'),1); } } + $name = &LONCAPA::map::qtunescape($name); $url = &LONCAPA::map::qtunescape($url); $LONCAPA::map::resources[$residx] = join(':', ($name, $url, $ext, 'normal', 'res')); @@ -807,7 +982,6 @@ END &storemap($coursenum, $coursedom, $folder.'.'.$container,1); unless ($fatal) { if ($folder =~ /^supplemental/) { - &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1); my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $folder.'.'.$container); } @@ -877,13 +1051,14 @@ sub log_docs { } sub docs_change_log { - my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath)=@_; + my ($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath,$canedit)=@_; my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); + my $navmap; my $js = ''."\n". -'
'. +''. '

'. &mt($message,' "/adm/coursedocs?tools=1&verify=1&checkstale=$env{'form.checkstale'}", + text=>'Results', + faq=>273, + bug=>'Instructor Interface'}); + &verifycontent($r,$env{'form.checkstale'}); + } else { + &contentverifyform($r); + } } elsif ($allowed && $env{'form.listsymbs'}) { &init_breadcrumbs('listsymbs','List Content IDs'); &list_symbs($r); + } elsif ($allowed && $env{'form.shorturls'}) { + &init_breadcrumbs('shorturls','Set/Display Shortened URLs','Docs_Short_URLs'); + &short_urls($r,$canedit); } elsif ($allowed && $env{'form.docslog'}) { &init_breadcrumbs('docslog','Show Log'); my $folder = $env{'form.folder'}; if ($folder eq '') { $folder='default'; } - &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath); + &docs_change_log($r,$coursenum,$coursedom,$folder,$allowed,$crstype,$iconpath,$canedit); } elsif ($allowed && $env{'form.versions'}) { &init_breadcrumbs('versions','Check/Set Resource Versions','Docs_Check_Resource_Versions'); - &checkversions($r); - } elsif ($allowed && $env{'form.dumpcourse'}) { + &checkversions($r,$canedit); + } elsif ($canedit && $env{'form.dumpcourse'}) { &init_breadcrumbs('dumpcourse','Copy '.&Apache::loncommon::course_type().' Content to Authoring Space'); &dumpcourse($r); - } elsif ($allowed && $env{'form.exportcourse'}) { + } elsif ($canedit && $env{'form.exportcourse'}) { &init_breadcrumbs('exportcourse','IMS Export'); &Apache::imsexport::exportcourse($r); } else { - if ($allowed && $env{'form.authorrole'}) { + if ($canedit && $env{'form.authorrole'}) { $noendpage = 1; my ($redirect,$error) = &makenewproblem($r,$coursedom,$coursenum); if ($redirect) { @@ -4957,6 +5658,8 @@ sub handler { $r->internal_redirect($redirect); return OK; } + } else { + $r->internal_redirect($redirect); } } } @@ -4966,10 +5669,30 @@ sub handler { # Get the parameters that may be needed # &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folderpath', + ['folderpath','title', 'forcesupplement','forcestandard', 'tools','symb','command','supppath']); + foreach my $item ('forcesupplement','forcestandard','tools') { + next if ($env{'form.'.$item} eq ''); + unless ($env{'form.'.$item} eq '1') { + delete($env{'form.'.$item}); + } + } + + if ($env{'form.command'}) { + unless ($env{'form.command'} =~ /^(direct|directnav|editdocs|editsupp|contents|home)$/) { + delete($env{'form.command'}); + } + } + + if ($env{'form.symb'}) { + my ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'}); + unless (($id =~ /^\d+$/) && (&Apache::lonnet::is_on_map($resurl))) { + delete($env{'form.symb'}); + } + } + # standard=1: this is a "new-style" course with an uploaded map as top level # standard=2: this is a "old-style" course, and there is nothing we can do @@ -4992,6 +5715,17 @@ sub handler { my $toolsflag=0; if ($env{'form.tools'}) { $toolsflag=1; } + if ($env{'form.folderpath'} ne '') { + &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom); + } + + my $backto_supppath; + if ($env{'form.supppath'} ne '') { + if ($supplementalflag && $allowed) { + $backto_supppath = &validate_supppath($coursenum,$coursedom); + } + } + my $script=''; my $showdoc=0; my $addentries = {}; @@ -4999,27 +5733,28 @@ sub handler { my $containertag; my $pathitem; my %ltitools; + my $posslti; + my $hiddentop; + my $navmap; + my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) }; # Do we directly jump somewhere? - if (($env{'form.command'} eq 'direct') || ($env{'form.command'} eq 'directnav')) { if ($env{'form.symb'} ne '') { $env{'form.folderpath'}= - &Apache::loncommon::symb_to_docspath($env{'form.symb'}); + &Apache::loncommon::symb_to_docspath($env{'form.symb'},\$navmap); &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}.'_'.$env{'form.symb'}}); - } elsif ($env{'form.supppath'} ne '') { + } elsif (($env{'form.supppath'} ne '') && $supplementalflag && $allowed) { $env{'form.folderpath'}=$env{'form.supppath'}; &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => - $env{'form.command'}.'_'.$env{'form.supppath'}}); + $env{'form.command'}.'_'.$backto_supppath}); } } elsif ($env{'form.command'} eq 'editdocs') { - $env{'form.folderpath'} = 'default&'. - &escape(&mt('Main Content').':::::'); + $env{'form.folderpath'} = &default_folderpath($coursenum,$coursedom,\$navmap); &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}}); } elsif ($env{'form.command'} eq 'editsupp') { - $env{'form.folderpath'} = 'supplemental&'. - &escape('Supplemental Content'); + $env{'form.folderpath'} = &supplemental_base(); &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/supplemental'}); } elsif ($env{'form.command'} eq 'contents') { &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/navmaps'}); @@ -5038,9 +5773,19 @@ sub handler { if ((!$env{'form.folderpath'}) && $allowed) { &Apache::loncommon::restore_course_settings($stored_folderpath, {'folderpath' => 'scalar'}); - unless (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) { + + if (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) { + if ($supplementalflag) { + undef($env{'form.folderpath'}) if ($1 eq 'default'); + } else { + undef($env{'form.folderpath'}) if ($1 eq 'supplemental'); + } + } else { undef($env{'form.folderpath'}); } + if ($env{'form.folderpath'} ne '') { + &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom); + } } # If we are not allowed to make changes, all we can see are supplemental docs @@ -5055,19 +5800,101 @@ sub handler { .'&'. $env{'form.folderpath'}; } +# If allowed and user's role is not advanced check folderpath is not hidden + my $hidden_and_empty; + if (($allowed) && (!$env{'request.role.adv'}) && ($env{'form.folderpath'} ne '')) { + my ($folderurl,$foldername,$hiddenfolder); + my @pathitems = split(/\&/,$env{'form.folderpath'}); + my $folder = $pathitems[-2]; + if ($folder eq '') { + undef($env{'form.folderpath'}); + } else { + $folderurl = "uploaded/$coursedom/$coursenum/$folder"; + if ((split(/\:/,$pathitems[-1]))[5]) { + $folderurl .= '.page'; + } else { + $folderurl .= '.sequence'; + } + if ($supplementalflag) { + ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*)::(|1):::$/); + $foldername = &HTML::Entities::decode(&unescape($foldername)); + my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom); + if (ref($supplemental) eq 'HASH') { + my ($suppmap,$suppmapnum); + if ($folder eq 'supplemental') { + $suppmap = 'default'; + $suppmapnum = 0; + } elsif ($folder =~ /^supplemental_(\d+)$/) { + $suppmap = $1; + $suppmapnum = $suppmap; + } + if ($hiddenfolder) { + my $hascontent; + foreach my $key (reverse(sort(keys(%{$supplemental->{'ids'}})))) { + if ($key =~ m{^\Q/uploaded/$coursedom/$coursenum/supplemental/$suppmap/\E}) { + $hascontent = 1; + } elsif (ref($supplemental->{'ids'}->{$key}) eq 'ARRAY') { + foreach my $id (@{$supplemental->{'ids'}->{$key}}) { + if ($id =~ /^$suppmapnum\:/) { + $hascontent = 1; + last; + } + } + } + last if ($hascontent); + } + unless ($hascontent) { + if ($foldername ne '') { + $hidden_and_empty = $foldername; + } else { + $hidden_and_empty = $folder; + } + } + } + } + } else { + unless (ref($navmap)) { + $navmap = Apache::lonnavmaps::navmap->new(); + } + ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*):|\d+:|1:(|1):|1:|1$/); + $foldername = &HTML::Entities::decode(&unescape($foldername)); + if (ref($navmap)) { + if ($hiddenfolder || + (lc($navmap->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes')) { + my @resources = $navmap->retrieveResources($folderurl,$filterFunc,1,1); + unless (@resources) { + if ($foldername ne '') { + $hidden_and_empty = $foldername; + } else { + $hidden_and_empty = $folder; + } + } + } + } + } + if ($hidden_and_empty ne '') { + splice(@pathitems,-2); + if (@pathitems) { + $env{'form.folderpath'} = join('&',@pathitems); + } else { + undef($env{'form.folderpath'}); + } + } + } + } + # If after all of this, we still don't have any paths, make them unless ($env{'form.folderpath'}) { if ($supplementalflag) { $env{'form.folderpath'}=&supplemental_base(); - } else { - $env{'form.folderpath'}='default&'.&escape(&mt('Main Content'). - ':::::'); + } elsif ($allowed) { + ($env{'form.folderpath'},$hiddentop) = &default_folderpath($coursenum,$coursedom,\$navmap); } } # Store this unless ($toolsflag) { - if ($allowed) { + if (($allowed) && ($env{'form.folderpath'} ne '')) { &Apache::loncommon::store_course_settings($stored_folderpath, {'folderpath' => 'scalar'}); } @@ -5085,8 +5912,12 @@ sub handler { } else { if ($env{'form.folder'} eq '' || $env{'form.folder'} eq 'supplemental') { - $folderpath='default&'. - &escape(&mt('Main Content').':::::'); + if ($env{'form.folder'} eq 'supplemental') { + $folderpath=&supplemental_base(); + } elsif (!$hiddentop) { + $folderpath='default&'. + &escape(&mt('Main Content').':::::'); + } } } $containertag = ''; @@ -5097,7 +5928,7 @@ sub handler { if ($showdoc) { # got called in sequence from course $allowed=0; } else { - if ($allowed) { + if ($canedit) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['cmd']); $script=&Apache::lonratedt::editscript('simple'); } @@ -5126,7 +5957,7 @@ sub handler { my $tid = 1; my @tabids; if ($supplementalflag) { - @tabids = ('002','ee2','ff2'); + @tabids = ('002','dd2','ee2','ff2'); $tid = 2; } else { @tabids = ('aa1','bb1','cc1','ff1'); @@ -5136,16 +5967,34 @@ sub handler { } } my $tabidstr = join("','",@tabids); - %ltitools = &Apache::lonnet::get_domain_ltitools($coursedom); - my $posslti = keys(%ltitools); + my (%domtools,%crstools); + my %tooltypes = &Apache::loncommon::usable_exttools(); + if ($tooltypes{'dom'}) { + %domtools = &Apache::lonnet::get_domain_lti($coursedom,'consumer'); + } + if ($tooltypes{'crs'}) { + %crstools = &Apache::lonnet::get_course_lti($coursenum,$coursedom,'consumer'); + } + %ltitools = ( + dom => \%domtools, + crs => \%crstools, + ); + $posslti = scalar(keys(%domtools)) + scalar(keys(%crstools)); + my $hostname = $r->hostname(); $script .= &editing_js($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti, - $londocroot). + $londocroot,$canedit,$hostname,\$navmap). &history_tab_js(). &inject_data_js(). &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid). &Apache::lonextresedit::extedit_javascript(\%ltitools); + my $onload = "javascript:resize_scrollbox('contentscroll','1','1');"; + if ($hidden_and_empty ne '') { + my $alert = &mt("Additional privileges required to edit empty and hidden folder: '[_1]'", + $hidden_and_empty); + $onload .= "javascript:alert('".&js_escape($alert)."');"; + } $addentries = { - onload => "javascript:resize_scrollbox('contentscroll','1','1');", + onload => $onload, }; } $script .= &paste_popup_js(); @@ -5167,37 +6016,69 @@ sub handler { &Apache::lonhtmlcommon::clear_breadcrumbs(); if ($showdoc) { - $r->print(&Apache::loncommon::start_page("$crstype documents",undef, - {'force_register' => $showdoc,})); + my $args; + if ($supplementalflag) { + my $title = &HTML::Entities::encode($env{'form.title'},'\'"<>&'); + my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1); + $args = {'bread_crumbs' => $brcrum}; + } else { + $args = {'force_register' => $showdoc}; + } + $r->print(&Apache::loncommon::start_page("$crstype documents",undef,$args)); } elsif ($toolsflag) { + my ($breadtext,$breadtitle); + $breadtext = "$crstype Editor"; + if ($canedit) { + $breadtitle = 'Editing '.$crstype.' Contents'; + } else { + $breadtext .= ' (View-only mode)'; + $breadtitle = 'Viewing '.$crstype.' Contents'; + } &Apache::lonhtmlcommon::add_breadcrumb({ - href=>"/adm/coursedocs",text=>"$crstype Contents"}); + href=>"/adm/coursedocs",text=>$breadtext}); $r->print(&Apache::loncommon::start_page("$crstype Contents", $script) .&Apache::loncommon::help_open_menu('','',273,'RAT') .&Apache::lonhtmlcommon::breadcrumbs( - 'Editing Course Contents') + $breadtitle) ); } elsif ($r->uri eq '/adm/supplemental') { + unless ($env{'request.role.adv'}) { + unless (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom)) { + $r->internal_redirect('/adm/navmaps'); + return OK; + } + } my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype); $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef, {'bread_crumbs' => $brcrum,})); } else { + my ($breadtext,$breadtitle,$helpitem); + $breadtext = "$crstype Editor"; + if ($canedit) { + $breadtitle = 'Editing '.$crstype.' Contents'; + $helpitem = 'Docs_Adding_Course_Doc'; + } else { + $breadtext .= ' (View-only mode)'; + $breadtitle = 'Viewing '.$crstype.' Contents'; + $helpitem = 'Docs_Viewing_Course_Doc'; + } &Apache::lonhtmlcommon::add_breadcrumb({ - href=>"/adm/coursedocs",text=>"$crstype Contents"}); + href=>"/adm/coursedocs",text=>$breadtext}); $r->print(&Apache::loncommon::start_page("$crstype Contents", $script, {'add_entries' => $addentries} ) .&Apache::loncommon::help_open_menu('','',273,'RAT') .&Apache::lonhtmlcommon::breadcrumbs( - 'Editing '.$crstype.' Contents', - 'Docs_Adding_Course_Doc') + $breadtitle, + $helpitem) ); } my %allfiles = (); my %codebase = (); my ($upload_result,$upload_output,$uploadphase); - if ($allowed) { + if ($canedit) { + undef($suppchanges); if (($env{'form.uploaddoc.filename'}) && ($env{'form.cmd'}=~/^upload_(\w+)/)) { my $context = $1; @@ -5205,9 +6086,14 @@ sub handler { undef($hadchanges); $uploadphase = &process_file_upload(\$upload_output,$coursenum,$coursedom, \%allfiles,\%codebase,$context,$crstype); + undef($navmap); if ($hadchanges) { &mark_hash_old(); } + if ($suppchanges) { + &Apache::lonnet::update_supp_caches($coursedom,$coursenum); + undef($suppchanges); + } $r->print($upload_output); } elsif ($env{'form.phase'} eq 'upload_embedded') { # Process file upload - phase two - upload embedded objects @@ -5220,7 +6106,7 @@ sub handler { my ($destination,$dir_root) = &embedded_destination(); my $url_root = '/uploaded/'.$docudom.'/'.$docuname; my $actionurl = '/adm/coursedocs'; - my ($result,$flag) = + my ($result,$flag) = &Apache::loncommon::upload_embedded('coursedoc',$destination, $docuname,$docudom,$dir_root,$url_root,undef,undef,undef,$state, $actionurl); @@ -5231,11 +6117,11 @@ sub handler { my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'}; my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'}; my ($destination,$dir_root) = &embedded_destination(); - my $result = + my $result = &Apache::loncommon::modify_html_refs('coursedoc',$destination, $docuname,$docudom,undef, $dir_root); - $r->print($result.&return_to_editor()); + $r->print($result.&return_to_editor()); } elsif ($env{'form.phase'} eq 'decompress_uploaded') { $uploadphase = 'decompress_phase_one'; $r->print(&decompression_phase_one(). @@ -5249,7 +6135,7 @@ sub handler { if ($allowed && $toolsflag) { $r->print(&startContentScreen('tools')); - $r->print(&generate_admin_menu($crstype)); + $r->print(&generate_admin_menu($crstype,$canedit)); $r->print(&endContentScreen()); } elsif ((!$showdoc) && (!$uploadphase)) { # ----------------------------------------------------------------------------- @@ -5261,7 +6147,7 @@ sub handler { 'impo' => 'Import', 'lnks' => 'Import from Stored Links', 'impm' => 'Import from Assembled Map', - 'imcr' => 'Import from Course Resources', + 'imcr' => 'Import from Course Resources', 'extr' => 'External Resource', 'extt' => 'External Tool', 'selm' => 'Select Map', @@ -5272,10 +6158,11 @@ sub handler { 'navc' => 'Table of Contents', 'sipa' => 'Simple Course Page', 'sipr' => 'Simple Problem', - 'webp' => 'Blank Web Page (editable)', + 'webp' => 'Blank Web Page (editable)', 'stpr' => 'Standard Problem', 'news' => 'New sub-directory', 'crpr' => 'Create Problem', + 'swit' => 'Switch Server', 'drbx' => 'Drop Box', 'scuf' => 'External Scores (handgrade, upload, clicker)', 'bull' => 'Discussion Board', @@ -5296,6 +6183,7 @@ sub handler { 'dire' => 'Directory:', 'cate' => 'Category:', 'tmpl' => 'Template:', + 'empd' => 'No resources found', 'comment' => 'Comment', 'parse' => 'Upload embedded images/multimedia files if HTML file', 'bb5' => 'Blackboard 5', @@ -5304,6 +6192,7 @@ sub handler { 'webctce4' => 'WebCT 4 Campus Edition', 'yes' => 'Yes', 'no' => 'No', + 'er' => 'Editing rights unavailable for your current role.', ); # ----------------------------------------------------------------------------- @@ -5333,7 +6222,7 @@ sub handler { if ($disk_quota == 0) { $percent = 100.0; } else { - $percent = 100*($current_disk_usage/$disk_quota); + $percent = 100*($usage/$disk_quota); } $usage = sprintf("%.2f",$usage); $quota = sprintf("%.2f",$quota); @@ -5344,8 +6233,8 @@ sub handler { my $fileupload=(< - - + + FIUP my $checkbox=(< --> CHBO my $imsfolder = $env{'form.folder'}; @@ -5370,7 +6259,7 @@ CHBO

$lt{'cms'}:  - @@ -5380,7 +6269,7 @@ CHBO

- +
IMSFORM @@ -5395,7 +6284,7 @@ IMSFORM $fileupload
$lt{'title'}:
- + $pathitem
@@ -5403,11 +6292,17 @@ IMSFORM $checkbox
- + FUFORM + my $mapimportjs; + if ($canedit) { + $mapimportjs = "javascript:openbrowser('mapimportform','importmap','sequence,page','');"; + } else { + $mapimportjs = "javascript:alert('".&js_escape($lt{'er'})."');"; + } my $importpubform=(< $lt{'impm'}$help{'Load_Map'} @@ -5418,63 +6313,80 @@ FUFORM $lt{'copm'}
-  $lt{'selm'}
- + onfocus="this.blur();$mapimportjs" $disabled /> +  $lt{'selm'}
+ SEDFFORM my $importcrsresform; my ($numdirs,$pickfile) = - &Apache::loncommon::import_crsauthor_form('crsresimportform','coursepath','coursefile', + &Apache::loncommon::import_crsauthor_form('coursepath','coursefile', "resize_scrollbox('contentscroll','1','0');", undef,'res'); if ($pickfile) { $importcrsresform=(< + $lt{'imcr'}$help{'Course_Resources'}
CRSFORM } + my $fromstoredjs; + if ($canedit) { + $fromstoredjs = 'open_StoredLinks_Import()'; + } else { + $fromstoredjs = "alert('".&js_escape($lt{'er'})."')"; + } + my @importpubforma = ( { ''.$lt{srch}.'' => $pathitem."$lt{'srch'}" }, { ''.$lt{impo}.'' => "$lt{'impo'}$help{'Importing_LON-CAPA_Resource'}" }, - { ''.$lt{lnks}.'' => "$lt{'lnks'}" }, + { ''.$lt{lnks}.'' => ''.$lt{'lnks'}.'' }, { ''.$lt{impm}.'' => $importpubform }, ); if ($pickfile) { - push(@importpubforma,{ ''.$lt{imcr}.'' => $importcrsresform}); + push(@importpubforma,{ ''.$lt{imcr}.'' => $importcrsresform}); } $importpubform = &create_form_ul(&create_list_elements(@importpubforma)); my $extresourcesform = &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem, - $help{'Adding_External_Resource'}); + $help{'Adding_External_Resource'}, + undef,undef,undef,undef,undef,undef,$disabled); my $exttoolform = &Apache::lonextresedit::extedit_form(0,0,undef,undef,$pathitem, $help{'Adding_External_Tool'},undef, undef,'tool',$coursedom,$coursenum, - \%ltitools); + \%ltitools,$disabled); if ($allowed) { my $folder = $env{'form.folder'}; if ($folder eq '') { $folder='default'; } - my $output = &update_paste_buffer($coursenum,$coursedom,$folder); - if ($output) { - $r->print($output); + if ($canedit) { + my $output = &update_paste_buffer($coursenum,$coursedom,$folder); + if ($output) { + $r->print($output); + } } $r->print(< @@ -5484,6 +6396,11 @@ CRSFORM $containertag +
+ + + $containertag +
HIDDENFORM $r->print(&makesimpleeditform($pathitem)."\n". @@ -5506,12 +6423,12 @@ HIDDENFORM } # - + my $hostname = $r->hostname(); my $savefolderpath; if ($allowed) { my $folder=$env{'form.folder'}; - if ($folder eq '' || $supplementalflag) { + if ((($folder eq '') && (!$hiddentop)) || ($supplementalflag)) { $folder='default'; $savefolderpath = $env{'form.folderpath'}; $env{'form.folderpath'}='default&'.&escape(&mt('Main Content')); @@ -5520,9 +6437,13 @@ HIDDENFORM } my $postexec=''; if ($folder eq 'default') { + my $windowname = 'loncapaclient'; + if ($env{'request.lti.login'}) { + $windowname .= 'lti'; + } $r->print(''."\n" ); @@ -5535,17 +6456,17 @@ HIDDENFORM my $newnavform=(< - + $pathitem - $lt{'navc'} + $lt{'navc'} $help{'Navigate_Content'} NNFORM my $newsmppageform=(< - + $pathitem $lt{'sipa'} @@ -5555,7 +6476,7 @@ NSPFORM my $newsmpproblemform=(< - + $pathitem $lt{'sipr'} @@ -5566,7 +6487,7 @@ NSPROBFORM my $newdropboxform=(< - + $pathitem $lt{'drbx'} @@ -5576,7 +6497,7 @@ NDBFORM my $newexuploadform=(< - + $pathitem $lt{'scuf'} @@ -5586,7 +6507,7 @@ NEXUFORM my $newbulform=(< - + $pathitem $lt{'bull'} @@ -5596,18 +6517,18 @@ NBFORM my $newaboutmeform=(< - + $pathitem - $lt{'mypi'} + $lt{'mypi'} $help{'My Personal Information Page'} NAMFORM my $newaboutsomeoneform=(< - + $pathitem $lt{'abou'} @@ -5616,11 +6537,11 @@ NASOFORM my $newrosterform=(< - + $pathitem - $lt{'rost'} + $lt{'rost'} $help{'Course_Roster'} NROSTFORM @@ -5637,7 +6558,7 @@ NROSTFORM } my $newwebpageform =(< - + $pathitem $lt{'webp'} @@ -5646,133 +6567,62 @@ NROSTFORM NWEBFORM my @ids=&Apache::lonnet::current_machine_ids(); - my %select_menus; - my $numauthor = 0; - my $numcrsdirs = 0; - my $toppath = "/priv/$env{'user.domain'}/$env{'user.name'}"; + my $machines_str = "'".join("','",@ids)."'"; + my (%is_home,%toppath,$rolehomes); if ($env{'user.author'}) { - $numauthor ++; - $select_menus{'author'}->{'text'} = &Apache::lonnet::plaintext('au'); if (grep(/^\Q$env{'user.home'}\E$/,@ids)) { - my $is_home = 1; - my %subdirs; - &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs); - $select_menus{'author'}->{'default'} = '/'; - $select_menus{'author'}->{'select2'}->{'/'} = '/'; - my @ordered = ('/'); - foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) { - $select_menus{'author'}->{'select2'}->{$relpath} = $relpath; - push(@ordered,$relpath); - } - $select_menus{'author'}->{'order'} = \@ordered; - } else { - $select_menus{'author'}->{'select2'}->{'switch'} = &mt('Switch server required'); - $select_menus{'author'}->{'default'} = 'switch'; - $select_menus{'author'}->{'order'} = ['switch']; + $is_home{'author'} = 1; } + $rolehomes = ''."\n"; } my %roleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles', ['active'],['ca','aa']); - my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'}; my %by_roletype; if (keys(%roleshash)) { foreach my $entry (keys(%roleshash)) { my ($auname,$audom,$roletype) = split(/:/,$entry); my $key = $entry; $key =~ s/:/___/g; - $by_roletype{$roletype}{$auname.'___'.$audom} = 1; - $select_menus{$key}->{'text'} = &Apache::lonnet::plaintext($roletype)." ($audom/$auname)"; + my $author = $auname.'___'.$audom; + $by_roletype{$roletype}{$author} = 1; my $rolehome = &Apache::lonnet::homeserver($auname,$audom); - if (grep(/^\Q$rolehome\E$/,@ids)) { - my $is_home = 1; - my (%subdirs,@ordered); - my $toppath="/priv/$audom/$auname"; - &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs); - $select_menus{$key}->{'default'} = '/'; - $select_menus{$key}->{'select2'}->{'/'} = '/'; - my @ordered = ('/'); - foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) { - $select_menus{$key}->{'select2'}->{$relpath} = $relpath; - push(@ordered,$relpath); - } - $select_menus{$key}->{'order'} = \@ordered; - } else { - $select_menus{$key}->{'select2'}->{'switch'} = &mt('Switch server required'); - $select_menus{$key}->{'default'} = 'switch'; - $select_menus{$key}->{'order'} = ['switch']; - } - $numauthor ++; - } - } - my ($pickdir,$showtitle);; - if ($numauthor) { - my @order; - my $defrole; - if ($env{'user.author'}) { - push(@order,'author'); - $defrole = 'author'; - } - if (keys(%by_roletype)) { - foreach my $possrole ('ca','aa') { - if (ref($by_roletype{$possrole}) eq 'HASH') { - foreach my $author (sort { lc($a) cmp lc($b) } (keys(%{$by_roletype{$possrole}}))) { - unless ($defrole) { - $defrole = $author; - } - push(@order,$author.'___'.$possrole); - } - } + $toppath{$author} = "/priv/$audom/$auname"; + if (grep(/^\Q$rolehome\E$/,@ids)) { + $is_home{$author} = 1; } + $rolehomes .= ''."\n"; } - $select_menus{'course'}->{'text'} = &mt('Course Resource'); - if (grep(/^\Q$crshome\E$/,@ids)) { - my $is_home = 1; - my %subdirs; - my $toppath="/priv/$coursedom/$coursenum"; - &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs); - $numcrsdirs = keys(%subdirs); - $select_menus{'course'}->{'default'} = '/'; - $select_menus{'course'}->{'select2'}->{'/'} = '/'; - my @ordered = ('/'); - foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) { - $select_menus{'course'}->{'select2'}->{$relpath} = $relpath; - push(@ordered,$relpath); - } - $select_menus{'course'}->{'order'} = \@ordered; - } else { - $select_menus{'course'}->{'select2'}->{'switch'} = &mt('Switch server required'); - $select_menus{'course'}->{'default'} = 'switch'; - $select_menus{'course'}->{'order'} = ['switch']; - } - push(@order,'course'); - $pickdir = $lt{'loca'}. - &Apache::loncommon::linked_select_forms('courseresform','
'.$lt{'dire'}, - $defrole,'authorrole','authorpath', - \%select_menus,\@order,'toggleCrsResTitle();', - '','priv').'
'; - $showtitle = 'none'; - } else { - my $is_home; - $showtitle = 'inline'; - if (grep(/^\Q$crshome\E$/,@ids)) { - $is_home = 1; - $pickdir .= ''; - my $toppath="/priv/$coursedom/$coursenum'}"; - my %subdirs; - &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs); - $numcrsdirs = keys(%subdirs); - if ($numcrsdirs) { - $pickdir .= &mt('Directory: ').''."\n"; + my $pickdir = $lt{'loca'}. + ''; - } else { - $pickdir .= ''."\n"; } } } + $pickdir .= ''."\n". + '
'."\n". + $lt{'dire'}. + '
'."\n"; my %seltemplate_menus; my @files = &Apache::lonhomework::get_template_list('problem'); @@ -5815,39 +6665,41 @@ NWEBFORM my $templatepreview = ''. ''.&mt('Example').''; my $crsresform=(< + $lt{'stpr'}$help{'Course_Resource'}
@@ -5900,7 +6757,7 @@ NFFORM $pathitem - $lt{'syll'} + $lt{'syll'} $help{'Syllabus'} @@ -5908,32 +6765,40 @@ NSYLFORM my $newgroupfileform=(< - + $pathitem - $lt{'grpo'} + $lt{'grpo'} $help{'Group Portfolio'} NGFFORM - @specialdocumentsforma=( + if ($container eq 'page') { + @specialdocumentsforma=( + {''.$lt{webp}.''=>$newwebpageform}, + ); + } else { + @specialdocumentsforma=( {''.$lt{newp}.''=>$newpageform}, - {''.$lt{syll}.''=>$newsylform}, - {''.$lt{navc}.''=>$newnavform}, + {''.$lt{syll}.''=>$newsylform}, + {''.$lt{navc}.''=>$newnavform}, {''.$lt{sipa}.''=>$newsmppageform}, {''.$lt{webp}.''=>$newwebpageform}, - ); + ); + } $specialdocumentsform = &create_form_ul(&create_list_elements(@specialdocumentsforma)); - - my @importdoc = ( - {''.$lt{extr}.''=>$extresourcesform} - ); - if (keys(%ltitools)) { - push(@importdoc, - {''.$lt{extt}.''=>$exttoolform}, + my @external = ( + {''.$lt{extr}.''=>$extresourcesform} ); + if ($posslti) { + push(@external, + {''.$lt{extt}.''=>$exttoolform}, + ); } + my $externalform = &create_form_ul(&create_list_elements(@external)); + + my @importdoc = (); unless ($container eq 'page') { push(@importdoc, {''.$lt{imsf}.''=>$imspform} @@ -5948,7 +6813,7 @@ NGFFORM {''.$lt{sipr}.''=>$newsmpproblemform}, {''.$lt{drbx}.''=>$newdropboxform}, {''.$lt{scuf}.''=>$newexuploadform}, - {''.$lt{stpr}.''=>$crsresform}, + {''.$lt{stpr}.''=>$crsresform}, ); $gradingform = &create_form_ul(&create_list_elements(@gradingforma)); @@ -5956,32 +6821,37 @@ NGFFORM {''.$lt{bull}.''=>$newbulform}, {''.$lt{mypi}.''=>$newaboutmeform}, {''.$lt{abou}.''=>$newaboutsomeoneform}, - {''.$lt{rost}.''=>$newrosterform}, - {''.$lt{grpo}.''=>$newgroupfileform}, + {''.$lt{rost}.''=>$newrosterform}, + {''.$lt{grpo}.''=>$newgroupfileform}, ); $communityform = &create_form_ul(&create_list_elements(@communityforma)); my %orderhash = ( 'aa' => ['Upload',$fileuploadform], 'bb' => ['Import',$importpubform], - 'cc' => ['Grading',$gradingform], + 'cc' => ['External',$externalform], + 'dd' => ['Grading',$gradingform], + 'ff' => ['Other',$specialdocumentsform], ); unless ($container eq 'page') { $orderhash{'00'} = ['Newfolder',$newfolderform]; - $orderhash{'dd'} = ['Collaboration',$communityform]; - $orderhash{'ee'} = ['Other',$specialdocumentsform]; + $orderhash{'ee'} = ['Collaboration',$communityform]; } $hadchanges=0; unless (($supplementalflag || $toolsflag)) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,\%orderhash,$iconpath,$pathitem,\%ltitools); + $supplementalflag,\%orderhash,$iconpath,$pathitem, + \%ltitools,$canedit,$hostname,\$navmap,$hiddentop); + undef($navmap); if ($error) { $r->print('

'.$error.'

'); } if ($hadchanges) { - &mark_hash_old(); - } + unless (&is_hash_old()) { + &mark_hash_old(); + } + } &changewarning($r,''); } @@ -5993,7 +6863,7 @@ unless ($container eq 'page') { unless ($supplementalflag) { $folder='supplemental'; } - if ($folder =~ /^supplemental$/ && + if (($folder eq 'supplemental') && (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) { $env{'form.folderpath'} = &supplemental_base(); } elsif ($allowed) { @@ -6011,7 +6881,7 @@ unless ($container eq 'page') {
SUPDOCFORM @@ -6040,13 +6911,15 @@ SNFFORM my $supextform = &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, - $help{'Adding_External_Resource'}); + $help{'Adding_External_Resource'}, + undef,undef,undef,undef,undef,undef, + $disabled); my $supexttoolform = &Apache::lonextresedit::extedit_form(1,0,undef,undef,$pathitem, $help{'Adding_External_Tool'}, undef,undef,'tool',$coursedom, - $coursenum,\%ltitools); + $coursenum,\%ltitools,$disabled); my $supnewsylform=(< @@ -6054,7 +6927,7 @@ SNFFORM $pathitem - $lt{'syll'} + $lt{'syll'} $help{'Syllabus'} SNSFORM @@ -6065,7 +6938,7 @@ SNSFORM $pathitem - $lt{'mypi'} + $lt{'mypi'} $help{'My Personal Information Page'} SNAMFORM @@ -6092,22 +6965,22 @@ SWEBFORM my @specialdocs = ( - {''.$lt{syll}.'' + {''.$lt{syll}.'' =>$supnewsylform}, - {''.$lt{mypi}.'' + {''.$lt{mypi}.'' =>$supnewaboutmeform}, {''.$lt{webp}.''=>$supwebpageform}, ); -my @supimportdoc = ( - {''.$lt{extr}.'' - =>$supextform}); - if (keys(%ltitools)) { - push(@supimportdoc, - {''.$lt{extt}.'' + my @supexternal = ( + {''.$lt{extr}.'' + =>$supextform}); + if ($posslti) { + push(@supexternal, + {''.$lt{extt}.'' =>$supexttoolform}); } - push(@supimportdoc, + my @supimportdoc = ( {''.$lt{upl}.'' =>$supupdocform}, ); @@ -6115,32 +6988,27 @@ my @supimportdoc = ( $supupdocform = &create_form_ul(&create_list_elements(@supimportdoc)); my %suporderhash = ( '00' => ['Supnewfolder', $supnewfolderform], - 'ee' => ['Upload',$supupdocform], + 'dd' => ['Upload',$supupdocform], + 'ee' => ['External',&create_form_ul(&create_list_elements(@supexternal))], 'ff' => ['Other',&create_form_ul(&create_list_elements(@specialdocs))] ); if ($supplementalflag) { - my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,\%suporderhash,$iconpath,$pathitem,\%ltitools); - if ($error) { - $r->print('

'.$error.'

'); - } else { - if ($suppchanges) { - my %servers = &Apache::lonnet::internet_dom_servers($coursedom); - my @ids=&Apache::lonnet::current_machine_ids(); - foreach my $server (keys(%servers)) { - next if (grep(/^\Q$server\E$/,@ids)); - my $hashid=$coursenum.':'.$coursedom; - my $cachekey = &escape('suppcount').':'.&escape($hashid); - &Apache::lonnet::remote_devalidate_cache($server,[$cachekey]); - } - &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1); - undef($suppchanges); - } - } + $suppchanges = 0; + my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, + $supplementalflag,\%suporderhash,$iconpath,$pathitem, + \%ltitools,$canedit,$hostname); + if ($error) { + $r->print('

'.$error.'

'); + } + if ($suppchanges) { + &Apache::lonnet::update_supp_caches($coursedom,$coursenum); + undef($suppchanges); + } } } elsif ($supplementalflag) { my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype, - $supplementalflag,'',$iconpath,$pathitem); + $supplementalflag,'',$iconpath,$pathitem,'',$canedit, + $hostname); if ($error) { $r->print('

'.$error.'

'); } @@ -6167,7 +7035,7 @@ my %suporderhash = ( &entryline(0,&mt("Click to download or use your browser's Save Link function"),$showdoc).''); } } - unless ($noendpage) { + unless ($noendpage) { $r->print(&Apache::loncommon::end_page()); } return OK; @@ -6176,6 +7044,7 @@ my %suporderhash = ( sub embedded_form_elems { my ($phase,$primaryurl,$newidx) = @_; my $folderpath = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + $newidx =~s /\D+//g; return < @@ -6196,7 +7065,11 @@ sub embedded_destination { } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { $destination .= $2.'/'; } - $destination .= $env{'form.newidx'}; + my $newidx = $env{'form.newidx'}; + $newidx =~s /\D+//g; + if ($newidx) { + $destination .= $newidx; + } my $dir_root = '/userfiles'; return ($destination,$dir_root); } @@ -6222,6 +7095,9 @@ sub decompression_info { } unshift(@hiddens,$pathitem); foreach my $item (@hiddens) { + if ($item eq 'newidx') { + next if ($env{'form.'.$item} =~ /\D/); + } if ($env{'form.'.$item}) { $hiddenelem .= ''."\n"; @@ -6239,7 +7115,7 @@ sub decompression_phase_one { $error = &mt('Archive file "[_1]" not in the expected location.',$env{'form.archiveurl'}); } else { my $file = $1; - $output = + $output = &Apache::loncommon::process_decompression($docudom,$docuname,$file, $destination,$dir_root, $hiddenelem); @@ -6296,6 +7172,10 @@ sub remove_archive { if ($url eq $env{'form.archiveurl'}) { if (&handle_edit_cmd($docuname,$docudom)) { ($errtext,$fatal) = &storemap($docuname,$docudom,$map,1); + if ($suppchanges) { + &Apache::lonnet::update_supp_caches($docudom,$docuname); + undef($suppchanges); + } if ($fatal) { if ($container eq 'page') { $delwarning = &mt('An error occurred updating the contents of the current page.'); @@ -6327,13 +7207,14 @@ sub remove_archive { } sub generate_admin_menu { - my ($crstype) = @_; + my ($crstype,$canedit) = @_; my $lc_crstype = lc($crstype); my ($home,$other,%outhash)=&authorhosts(); my %lt= ( # do not translate here 'vc' => 'Verify Content', 'cv' => 'Check/Set Resource Versions', 'ls' => 'List Resource Identifiers', + 'ct' => 'Display/Set Shortened URLs for Deep-linking', 'imse' => 'Export contents to IMS Archive', 'dcd' => "Copy $crstype Content to Authoring Space", ); @@ -6384,8 +7265,17 @@ sub generate_admin_menu { icon => 'symbs.png', linktitle => "List the unique identifier used for each resource instance in your $lc_crstype" }, + { linktext => $lt{'ct'}, + url => "javascript:injectData(document.courseverify,'dummy','shorturls','$lt{'ct'}')", + permission => 'F', + help => 'Docs_Short_URLs', + icon => 'shorturls.png', + linktitle => "Set shortened URLs for a resource or folder in your $lc_crstype for use in deep-linking" + }, ] - }, + }); + if ($canedit) { + push(@menu, { categorytitle=>'Export', items =>[ { linktext => $lt{'imse'}, @@ -6404,6 +7294,7 @@ sub generate_admin_menu { }, ] }); + } return '
'."\n". ''."\n". &Apache::lonhtmlcommon::generate_menu(@menu)."\n". @@ -6412,15 +7303,16 @@ sub generate_admin_menu { sub generate_edit_table { my ($tid,$orderhash_ref,$to_show,$iconpath,$jumpto,$readfile, - $need_save,$copyfolder) = @_; + $need_save,$copyfolder,$canedit) = @_; return unless(ref($orderhash_ref) eq 'HASH'); my %orderhash = %{$orderhash_ref}; - my $form; - my $activetab; - my $active; + my ($form, $activetab, $active, $disabled); if (($env{'form.active'} ne '') && ($env{'form.active'} ne '00')) { $activetab = $env{'form.active'}; } + unless ($canedit) { + $disabled = ' disabled="disabled"'; + } my $backicon = $iconpath.'clickhere.gif'; my $backtext = &mt('Exit Editor'); $form = '
'. @@ -6484,7 +7376,7 @@ sub generate_edit_table { - +
END @@ -6510,7 +7402,8 @@ END } sub editing_js { - my ($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti,$londocroot) = @_; + my ($udom,$uname,$supplementalflag,$coursedom,$coursenum,$posslti, + $londocroot,$canedit,$hostname,$navmapref) = @_; my %js_lt = &Apache::lonlocal::texthash( p_mnf => 'Name of New Folder', t_mnf => 'New Folder', @@ -6541,6 +7434,8 @@ sub editing_js { p_ctr2b => '?', p_ctr3a => 'Cut those', p_ctr3b => 'items?', + setal => 'Enter a (unique) alias', + delal => 'Are you sure you want to eliminate the alias?', rpck => 'Enter number to pick (e.g., 3)', imsfile => 'You must choose an IMS package for import', imscms => 'You must select which Course Management System was the source of the IMS package', @@ -6554,6 +7449,9 @@ sub editing_js { nofi => 'No file selected', tinc => 'Title in course', sunm => 'Sub-directory name', + edri => 'Editing rights unavailable for your current role.', + sele => 'Select', + swit => 'Switch server required', ); &js_escape(\%js_lt); my $crstype = &Apache::loncommon::course_type(); @@ -6562,11 +7460,12 @@ sub editing_js { if (&HTML::Entities::decode($env{'environment.internal.'.$env{'request.course.id'}.'.docs_folderpath.folderpath'}) =~ /\:1$/) { $main_container_page = 1; } - my $toplevelmain = - &escape(&mt('Main Content').':::::'); - my $toplevelsupp = &supplemental_base(); - my $backtourl; + my $toplevelmain = &escape(&default_folderpath($coursenum,$coursedom,$navmapref)); + my $toplevelsupp = &supplemental_base(); + my $showfile_js = &Apache::loncommon::show_crsfiles_js(); + my @ids=&Apache::lonnet::current_machine_ids(); + my $machines_str = "'".join("','",@ids)."'"; if ($env{'docs.exit.'.$env{'request.course.id'}} =~ /^direct_(.+)$/) { my $caller = $1; if ($caller =~ /^supplemental/) { @@ -6582,9 +7481,36 @@ sub editing_js { if (($caller =~ m{^([^#]+)\Q#$anchor\E$})) { $caller = $1.&escape('#').$anchor; } + } else { + $url = $res; + } + $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"'); + if ($backtourl =~ m{^\Q/uploaded/$coursedom/$coursenum/\Edefault_\d+\.sequence$}) { + $backtourl .= '?navmap=1'; + } else { + $backtourl .= '?symb='. + &HTML::Entities::encode($caller,'<>&"'); + } + if ($backtourl =~ m{^\Q/public/$coursedom/$coursenum/syllabus\E}) { + if (($ENV{'SERVER_PORT'} == 443) && + ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://})) { + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { + if ($hostname ne '') { + $backtourl = 'http://'.$hostname.$backtourl; + } + $backtourl .= (($backtourl =~ /\?/) ? '&':'?').'usehttp=1'; + } + } + } elsif ($backtourl =~ m{^/adm/wrapper/ext/(?!https:)}) { + if (($ENV{'SERVER_PORT'} == 443) && ($hostname ne '')) { + unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) { + if ($hostname ne '') { + $backtourl = 'http://'.$hostname.$backtourl; + } + $backtourl .= (($backtourl =~ /\?/) ? '&':'?').'usehttp=1'; + } + } } - $backtourl = &HTML::Entities::encode(&Apache::lonnet::clutter($url),'<>&"').'?symb='. - &HTML::Entities::encode($caller,'<>&"'); if ($anchor ne '') { $backtourl .= '#'.&HTML::Entities::encode($anchor,'<>&"'); } @@ -6596,30 +7522,39 @@ sub editing_js { } elsif ($env{'docs.exit.'.$env{'request.course.id'}} eq '/adm/menu') { $backtourl = '/adm/menu'; } elsif ($supplementalflag) { - $backtourl = '/adm/supplemental'; + if (($env{'request.role.adv'}) || + (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom))) { + $backtourl = '/adm/supplemental'; + } else { + $backtourl = '/adm/navmaps'; + } } else { $backtourl = '/adm/navmaps'; } - my $fieldsets = "'ext','doc'"; - if ($posslti) { - $fieldsets .= ",'tool'"; - } + my $fieldsets = "'doc'"; unless ($main_container_page) { $fieldsets .=",'ims'"; } + my $extfieldsets = "'ext'"; + if ($posslti) { + $extfieldsets .= ",'tool'"; + } if ($supplementalflag) { - $fieldsets = "'suppext','suppdoc'"; + $fieldsets = "'suppdoc'"; + $extfieldsets = "'suppext'"; if ($posslti) { - $fieldsets .= ",'supptool'"; + $extfieldsets .= ",'supptool'"; } } - return < 0) { - document.courseresform.authorrole.selectedIndex = 0; - select1priv_changed(); - document.courseresform.authorpath.selectedIndex = 0; - document.courseresform.newresourceadd.selectedIndex = 0; - toggleNewInCourse(document.courseresform); - if (document.getElementById('newresource')) { - document.getElementById('newresource').style.display = 'none'; - } - } else { - if (numcrsdirs) { - document.courseresform.authorpath.selectedIndex = 0; - } + document.courseresform.authorrole.selectedIndex = 0; + document.courseresform.authorpath.selectedIndex = 0; + document.courseresform.newresourceadd.selectedIndex = 0; + populateDirSelects(form,'authorrole','authorpath',1,0,0); + toggleNewInCourse(document.courseresform); + if (document.getElementById('newresource')) { + document.getElementById('newresource').style.display = 'none'; } if (document.courseresform.newresusetemp.length) { document.courseresform.newresusetemp[0].checked = true; @@ -6829,14 +7885,28 @@ function toggleNewsubdir(form) { function toggleCrsResTitle() { if (document.getElementById('newresource')) { - if (document.courseresform.authorrole.options[document.courseresform.authorrole.selectedIndex].value == 'course') { + var selloc = document.courseresform.authorrole.options[document.courseresform.authorrole.selectedIndex].value; + if (selloc == 'course') { document.getElementById('newresource').style.display = 'inline'; document.courseresform.newresourceadd[0].checked = true; toggleNewInCourse(document.courseresform); } else { document.getElementById('newresource').style.display = 'none'; } - } + } + if (document.getElementById('newstdproblem')) { + if (document.courseresform.authorpath.options[document.courseresform.authorpath.selectedIndex].value == 'switch') { + document.getElementById('newstdproblem').style.display = 'none'; + if (document.getElementById('stdprobswitch')) { + document.getElementById('stdprobswitch').style.display = 'block'; + } + } else { + document.getElementById('newstdproblem').style.display = 'block'; + if (document.getElementById('stdprobswitch')) { + document.getElementById('stdprobswitch').style.display = 'none'; + } + } + } } function toggleNewInCourse(form) { @@ -6916,16 +7986,28 @@ function getExample(width,height,scrolli } } -function toggleImportCrsres(caller,dircount) { +function toggleImportCrsres(caller) { var disp = 'none'; if (document.getElementById('importcrsresform')) { if (caller == 'res') { - var numdirs = parseInt(dircount); var curr = document.getElementById('importcrsresform').style.display; if (curr == 'none') { disp='block'; - if (numdirs > 1) { - select1res_changed(); + populateCrsSelects(document.crsresimportform,'coursepath','coursefile',1,'',1,0,1,1,0); + if ((document.getElementById('importcrsrescontent')) && + (document.getElementById('importcrsresempty'))) { + var selelem = document.crsresimportform.elements['coursepath']; + var numdirs = 0; + if (selelem.options.length) { + numdirs = selelem.options.length - 1; + } + if (numdirs) { + document.getElementById('importcrsrescontent').style.display='block'; + document.getElementById('importcrsresempty').style.display='none'; + } else { + document.getElementById('importcrsrescontent').style.display='none'; + document.getElementById('importcrsresempty').style.display='block'; + } } } } @@ -6935,6 +8017,152 @@ function toggleImportCrsres(caller,dirco return; } +$showfile_js + +function populateDirSelects(form,locsel,dirsel,setdir,recurse,nonemptydir) { + var location = form.elements[locsel].options[form.elements[locsel].selectedIndex].value; + if ((setdir) && (dirsel != null) && (dirsel != 'undefined') && (dirsel != '')) { + var selelem = form.elements[dirsel]; + var i, numfiles = selelem.options.length -1; + if (numfiles >=0) { + for (i = numfiles; i >= 0; i--) { + selelem.remove(i); + } + } + if ((location == '') || (location == null) || (location == 'undefined')) { + if (selelem.options.length == 0) { + selelem.options[selelem.options.length] = new Option('',''); + selelem.selectedIndex = 0; + } + if (document.getElementById('newstdproblem')) { + document.getElementById('newstdproblem').style.display = 'none'; + } + return; + } + var machineIds = new Array($machines_str); + var athome = 0; + var role = location; + if ((location == 'author') || (location == 'course')) { + if (document.getElementById('rolehome_'+location)) { + var currhome = document.getElementById('rolehome_'+location).value; + if ((currhome != '') && (currhome != null) && (currhome != 'undefined')) { + if (machineIds.includes(currhome)) { + athome = 1; + } + } + } + } else { + const roleinfo = location.split('___'); + role = encodeURIComponent(roleinfo[0]+'./'+roleinfo[1]); + if (document.getElementById('rolehome_coauthor_'+roleinfo[1]+'_'+roleinfo[0])) { + var currhome = document.getElementById('rolehome_coauthor_'+roleinfo[1]+'_'+roleinfo[0]).value; + if ((currhome != '') && (currhome != null) && (currhome != 'undefined')) { + if (machineIds.includes(currhome)) { + athome = 1; + } + } + } + } + if (athome) { + if (document.getElementById('stdprobswitch')) { + document.getElementById('stdprobswitch').style.display = 'none'; + } + if (document.getElementById('newstdproblem')) { + document.getElementById('newstdproblem').style.display = 'none'; + } + var http = new XMLHttpRequest(); + var url = "/adm/courseauthor"; + var params = "role="+role+"&rec="+recurse+"&nonempty="+nonemptydir+"&addtop=1"; + http.open("POST", url, true); + http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + http.onreadystatechange = function() { + if (http.readyState == 4 && http.status == 200) { + var data = JSON.parse(http.responseText); + if (Array.isArray(data.dirs)) { + var len = data.dirs.length; + if (len) { + if (len > 1) { + selelem.options[selelem.options.length] = new Option('$js_lt{sele}',''); + } + } + if (len) { + var j; + for (j = 0; j < len; j++) { + selelem.options[selelem.options.length] = new Option(data.dirs[j],data.dirs[j]); + } + selelem.selectedIndex = 0; + if (len == 1) { + toggleCrsResTitle(); + } + } + } + } + } + http.send(params); + } else { + selelem.options[selelem.options.length] = new Option('$js_lt{swit}','switch'); + selelem.selectedIndex = 0; + if (document.getElementById('stdprobswitch')) { + document.getElementById('stdprobswitch').style.display = 'block'; + } + if (document.getElementById('newstdproblem')) { + document.getElementById('newstdproblem').style.display = 'none'; + } + } + } + return; +} + +function switchForProb() { + if (document.courseresform.authorpath.options[document.courseresform.authorpath.selectedIndex].value == 'switch') { + var url = '/adm/switchserver?otherserver='; + var newhostid = ''; + var role = ''; + var selloc = document.courseresform.authorrole.options[document.courseresform.authorrole.selectedIndex].value; + if (selloc == 'author') { + newhostid = document.courseresform.rolehome_author.value; + role = "au./&js_escape($env{'user.domain'})/"; + } else if (selloc == 'course') { + newhostid = document.courseresform.rolehome_course.value; + role = "&js_escape($env{'request.role'})"; + } else { + var items = new Array(); + items = selloc.split('___'); + var len = document.courseresform.rolehome_coauthor.length; + if (null == len) { + var currval = document.courseresform.rolehome_coauthor.value; + if (null != currval) { + var info = new Array(); + info = currval.split('='); + newhostid = info[2]; + role = info[0]+'./'+info[1]; + } + } else { + for (var i=0; i END - close($fh); - } - if ((-e $sourcerights) && (-e "$sourcerights.meta")) { - if (!-e "$docroot/res/$coursedom") { - mkdir("$docroot/res/$coursedom",0755); - } - if (!-e "$docroot/res/$coursedom/$coursenum") { - mkdir("$docroot/res/$coursedom/$coursenum",0755); - } - if ((-e "$docroot/res/$coursedom/$coursenum") && (!-e $targetrights)) { - my $nokeyref = &Apache::lonpublisher::getnokey($r->dir_config('lonIncludes')); - my $output = &Apache::lonpublisher::batchpublish($r,$sourcerights,$targetrights,$nokeyref,1); - } + close($fh); } } - if ($env{'form.newresourceadd'}) { - my $template = $env{'form.template'}; - my $source = $docroot.$redirect; - my $target = $redirect; - $target =~ s{^/priv/}{/res/}; - $target = $docroot.$target; - if (!-e $source) { - my $copyfrom; - if ($template) { - my %templates; - my @files = &Apache::lonhomework::get_template_list('problem'); - foreach my $poss (@files) { - if (ref($poss) eq 'ARRAY') { - if ($template eq $poss->[0]) { - $templates{$template} = 1; - last; - } - } - } - if ($templates{$template}) { - $copyfrom = $template; - } - } - unless ($copyfrom) { - $copyfrom = $r->dir_config('lonIncludes').'/templates/blank.problem'; - } - &File::Copy::copy($copyfrom,$source); + if ((-e $sourcerights) && (-e "$sourcerights.meta")) { + if (!-e "$docroot/res/$coursedom") { + mkdir("$docroot/res/$coursedom",0755); + } + if (!-e "$docroot/res/$coursedom/$coursenum") { + mkdir("$docroot/res/$coursedom/$coursenum",0755); + } + if ((-e "$docroot/res/$coursedom/$coursenum") && (!-e $targetrights)) { + my $nokeyref = &Apache::lonpublisher::getnokey($r->dir_config('lonIncludes')); + my $output = &Apache::lonpublisher::batchpublish($r,$sourcerights,$targetrights,$nokeyref,1); } - if (!-e "$source.meta") { - my $cid = $coursedom.'_'.$coursenum; - my $now = time; - if (open(my $fh,">$source.meta")) { - my $author=$env{'environment.firstname'}.' '. - $env{'environment.middlename'}.' '. - $env{'environment.lastname'}.' '. - $env{'environment.generation'}; - $author =~ s/\s+$//; - my $title = $env{'form.newresourcetitle'}; - $title =~ s/^\s+|\s+$//g; - print $fh <$source.meta")) { + my $author=$env{'environment.firstname'}.' '. + $env{'environment.middlename'}.' '. + $env{'environment.lastname'}.' '. + $env{'environment.generation'}; + $author =~ s/\s+$//; + my $title = $env{'form.newresourcetitle'}; + $title =~ s/^\s+|\s+$//g; + print $fh < $author @@ -8002,8 +9199,7 @@ END $title END - close($fh); - } + close($fh); } } } @@ -8031,7 +9227,7 @@ END } sub finishnewprob { - my ($url,$path,$subdir,$newsubdir,$filename) = @_; + my ($url,$path,$subdir,$newsubdir,$filename,$context) = @_; unless (-d $path) { unless (mkdir($path,02770)) { return; @@ -8074,6 +9270,31 @@ sub finishnewprob { $redirect = "$url/$filename"; } } + if ((!-e $dest) && ($context ne 'upload')) { + my $template = $env{'form.template'}; + my $copyfrom; + if ($template ne '') { + my %templates; + my @files = &Apache::lonhomework::get_template_list('problem'); + foreach my $poss (@files) { + if (ref($poss) eq 'ARRAY') { + if ($template eq $poss->[0]) { + $templates{$template} = 1; + last; + } + } + } + if ($templates{$template}) { + $copyfrom = $template; + } + } + if ($filename =~ /\.problem$/) { + unless ($copyfrom) { + $copyfrom = $Apache::lonnet::perlvar{'lonIncludes'}.'/templates/blank.problem'; + } + &File::Copy::copy($copyfrom,$dest); + } + } return $redirect; } @@ -8185,7 +9406,9 @@ check on this Verify Content -=item devalidateversioncache() & checkversions() +=item devalidateversioncache() + +=item checkversions() Check Versions