--- loncom/interface/londocs.pm 2012/12/01 16:13:45 1.515 +++ loncom/interface/londocs.pm 2013/03/17 14:27:34 1.537 @@ -1,7 +1,7 @@ # The LearningOnline Network # Documents # -# $Id: londocs.pm,v 1.515 2012/12/01 16:13:45 raeburn Exp $ +# $Id: londocs.pm,v 1.537 2013/03/17 14:27:34 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -40,7 +40,6 @@ use Apache::lonxml; use Apache::lonclonecourse; use Apache::lonnavmaps; use Apache::lonnavdisplay(); -use Apache::lonuserstate(); use Apache::lonextresedit(); use HTML::Entities; use HTML::TokeParser; @@ -153,7 +152,7 @@ sub dumpcourse { $r->print(&endContentScreen()); return ''; } - my ($ca,$cd)=split(/\@/,$env{'form.authorspace'}); + my ($ca,$cd)=split(/\:/,$env{'form.authorspace'}); $r->print('

'.&mt('Copying Files').'

'); my $title=$env{'form.authorfolder'}; $title=&clean($title); @@ -271,7 +270,9 @@ sub dumpcourse { sub group_import { my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_; - + my ($donechk,$allmaps,%hierarchy,%titles,%addedmaps,%removefrommap, + %removeparam,$importuploaded,$fixuperrors); + $allmaps = {}; while (@files) { my ($name, $url, $residx) = @{ shift(@files) }; if (($url =~ m{^/uploaded/\Q$coursedom\E/\Q$coursenum\E/(default_\d+\.)(page|sequence)$}) @@ -288,7 +289,7 @@ sub group_import { $env{'form.output'}=$newmapstr; my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom, 'output',$1.$2); - if ($result != m|^/uploaded/|) { + if ($result !~ m{^/uploaded/}) { $errtext.='Map not saved: A network error occurred when trying to save the new map. '; $fatal = 2; } @@ -297,6 +298,24 @@ sub group_import { } } if ($url) { + if (($caller eq 'londocs') && + ($folder =~ /^default/)) { + if (($url =~ /\.(page|sequence)$/) && (!$donechk)) { + my $chome = &Apache::lonnet::homeserver($coursenum,$coursedom); + my $cid = $coursedom.'_'.$coursenum; + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $chome,$cid); + $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); + $importuploaded = 1; + } elsif ($url =~ m{^/res/.+\.(page|sequence)$}) { + next if ($allmaps->{$url}); + } + } if (!$residx || defined($LONCAPA::map::zombies[$residx])) { $residx = &LONCAPA::map::getresidx($url,$residx); @@ -306,11 +325,86 @@ sub group_import { if ($url=~m{^http://} || $url=~m{^https://}) { $ext = 'true'; } $url = &LONCAPA::map::qtunescape($url); $name = &LONCAPA::map::qtunescape($name); + if ($name eq '') { + $name = &mt('Web Page'); + } + if ($url =~ m{^/uploaded/$coursedom/$coursenum/((?:docs|supplemental)/(?:default|\d+))/new\.html$}) { + my $filepath = $1; + my $fname = $name; + if ($fname =~ /^\W+$/) { + $fname = 'web'; + } else { + $fname =~ s/\W/_/g; + } + if (length($fname > 15)) { + $fname = substr($fname,0,14); + } + my $initialtext = &mt('Replace with your own content.'); + my $newhtml = < + + + +$name + + +$initialtext + + +END + $env{'form.output'}=$newhtml; + my $result = + &Apache::lonnet::finishuserfileupload($coursenum,$coursedom, + 'output', + "$filepath/$residx/$fname.html"); + if ($result =~ m{^/uploaded/}) { + $url = $result; + if ($filepath =~ /^supplemental/) { + $name = time.'___&&&___'.$env{'user.name'}.'___&&&___'. + $env{'user.domain'}.'___&&&___'.$name; + } + } else { + return (&mt('Failed to save new web page.'),1); + } + } $LONCAPA::map::resources[$residx] = join(':', ($name, $url, $ext, 'normal', 'res')); } } - return &storemap($coursenum, $coursedom, $folder.'.'.$container,1); + if ($importuploaded) { + my %import_errors; + my %updated = ( + removefrommap => \%removefrommap, + removeparam => \%removeparam, + ); + my ($result,$msgsarray,$lockerror) = + &apply_fixups($folder,1,$coursedom,$coursenum,\%import_errors,\%updated); + if (keys(%import_errors) > 0) { + $fixuperrors = + '

'."\n". + &mt('The following files are either dependencies of a web page or references within a folder and/or composite page for which errors occurred during import:')."\n". + '

'."\n"; + } + if (ref($msgsarray) eq 'ARRAY') { + if (@{$msgsarray} > 0) { + $fixuperrors .= '

'. + join('
',@{$msgsarray}). + '

'; + } + } + if ($lockerror) { + $fixuperrors .= '

'. + $lockerror. + '

'; + } + } + my ($errtext,$fatal) = + &storemap($coursenum, $coursedom, $folder.'.'.$container,1); + return ($errtext,$fatal,$fixuperrors); } sub log_docs { @@ -391,18 +485,15 @@ sub docs_change_log { my %orderhash; my $container='sequence'; my $pathitem; - if ($env{'form.pagepath'}) { + if ($env{'form.folderpath'} =~ /\:1$/) { $container='page'; - $pathitem = ''; - } else { - my $folderpath=$env{'form.folderpath'}; - if ($folderpath eq '') { - $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents')); - } - $pathitem = ''; } + my $folderpath=$env{'form.folderpath'}; + if ($folderpath eq '') { + $folderpath = 'default&'.&escape(&mt('Main '.$crstype.' Documents').':::::'); + } + $pathitem = ''; my $readfile="/uploaded/$coursedom/$coursenum/$folder.$container"; my $jumpto = $readfile; $jumpto =~ s{^/}{}; @@ -654,7 +745,7 @@ sub print_paste_buffer { $is_external = 1; } - my ($canpaste,$nopaste,$othercrs,$areachange,$is_uploaded_map); + my ($canpaste,$nopaste,$othercrs,$areachange); if ($folder =~ /^supplemental/) { $canpaste = &supp_pasteable($env{'docs.markedcopy_url'}); unless ($canpaste) { @@ -699,7 +790,7 @@ sub print_paste_buffer { $buffer = $type.': '. &LONCAPA::map::qtescape($env{'docs.markedcopy_title'}).' ('. &LONCAPA::map::qtescape($env{'docs.markedcopy_url'}).')'; - } else { + } else { my $icon = &Apache::loncommon::icon($extension); if ($extension eq 'sequence' && $env{'docs.markedcopy_url'} =~ m{/default_\d+\.sequence$ }x) { @@ -711,19 +802,36 @@ sub print_paste_buffer { } if ($canpaste) { $r->print('
'.$buffer); - if (($is_uploaded_map) && (!$areachange)) { - if ((!$othercourse) && ($env{'docs.markedcopy_cmd'} eq 'cut')) { + if ((!$areachange) && (!$othercourse) && + ($env{'docs.markedcopy_cmd'} eq 'cut')) { + if (($is_uploaded_map) || + ($env{'docs.markedcopy_url'} =~ /(bulletinboard|smppg)$/) || + ($env{'docs.markedcopy_url'} =~ m{^/uploaded/$coursedom/$coursenum/(?:docs|supplemental)/(.+)$})) { + my ($copytext,$movetext); + if ($is_uploaded_map) { + $copytext = &mt('Copy to new folder'); + $movetext = &mt('Move old folder'); + } elsif ($env{'docs.markedcopy_url'} =~ /bulletinboard$/) { + $copytext = &mt('Copy to new bulletin board (not posts)'); + $movetext = &mt('Move old bulletin board (not posts)'); + } elsif ($env{'docs.markedcopy_url'} =~ /smppg$/) { + $copytext = &mt('Copy to new simple page'); + $movetext = &mt('Move old simple page'); + } else { + $copytext = &mt('Copy to new uploaded document'); + $movetext = &mt('Move old uploaded document'); + } $r->print((' 'x 4).''. ''. &mt('Show Paste Options').'
'. '
'.(' 'x 4). ''.(' ' x2). + $copytext.''.(' ' x2). '
'); - if ($env{'docs.markedcopy_nested'}) { + $movetext.'
'); + if (($is_uploaded_map) && ($env{'docs.markedcopy_nested'})) { $r->print('
'.&mt('Folder to paste contains sub-folders'). '
'); my @pastemaps = split(/\&/,$env{'docs.markedcopy_nested'}); @@ -761,16 +869,9 @@ sub print_paste_buffer { } } $r->print('
'.$othercrs); - if ($container eq 'page') { - $r->print(' - - -'); - } else { - $r->print(' + $r->print(' '); - } $r->print(''); } else { $r->print(&mt('Paste buffer contains:').' '.$buffer. @@ -905,30 +1006,23 @@ sub do_paste_from_buffer { %dbcopies,%zombies,%params,%docmoves,%mapmoves,%newsubdir,%newurls); $oldurl = $url; if ($is_map) { - if ($folder =~ /^default/) { - my $lastchange = &Apache::lonnet::get_coursechange($coursedom,$coursenum); - if ($lastchange > $env{'request.course.tied'}) { - &reinit_role($coursedom,$coursenum,$env{"course.$env{'request.course.id'}.home"}); - } - } # If pasting a map, check if map contains other maps - my (%allmaps,%hierarchy,%titles); + my ($allmaps,%hierarchy,%titles); + $allmaps = {}; if ($folder =~ /^default/) { - my $navmap = Apache::lonnavmaps::navmap->new(); - if (defined($navmap)) { - foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_map() },1,0,1)) { - $allmaps{$res->src()} = 1; - } - } + $allmaps = + &Apache::loncommon::allmaps_incourse($coursedom,$coursenum, + $env{"course.$env{'request.course.id'}.home"}, + $env{'request.course.id'}); } &contained_map_check($url,$folder,\%removefrommap,\%removeparam, - \%addedmaps,\%hierarchy,\%titles,\%allmaps); + \%addedmaps,\%hierarchy,\%titles,$allmaps); if ($url=~ m{^/uploaded/}) { my $newurl; unless ($env{'form.docs.markedcopy_options'} eq 'move') { ($newurl,my $error) = &get_newmap_url($url,$folder,$prefixchg,$coursedom,$coursenum, - $srcdom,$srcnum,\$title,\%allmaps,\%newurls); + $srcdom,$srcnum,\$title,$allmaps,\%newurls); if ($error) { return ($error); } @@ -943,15 +1037,17 @@ sub do_paste_from_buffer { } if (($srcdom ne $coursedom) || ($srcnum ne $coursenum) || ($prefixchg) || (($newurl ne '') && ($newurl ne $url))) { - unless (&url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum, - \%allmaps,\%rewrites,\%retitles,\%copies,\%dbcopies, + unless (&url_paste_fixups($url,$folder,$prefixchg,$coursedom, + $coursenum,$srcdom,$srcnum,$allmaps, + \%rewrites,\%retitles,\%copies,\%dbcopies, \%zombies,\%params,\%mapmoves,\%mapchanges,\%tomove, \%newsubdir,\%newurls)) { $mapmoves{$url} = 1; } $url = $newurl; } elsif ($env{'docs.markedcopy_nested'}) { - &url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum,\%allmaps,\%rewrites, + &url_paste_fixups($url,$folder,$prefixchg,$coursedom,$coursenum, + $srcdom,$srcnum,$allmaps,\%rewrites, \%retitles,\%copies,\%dbcopies,\%zombies,\%params,\%mapmoves, \%mapchanges,\%tomove,\%newsubdir,\%newurls); } @@ -960,28 +1056,40 @@ sub do_paste_from_buffer { &Apache::lonnet::delenv('docs.markedcopy'); # if pasting published map (main content are only) check map is not already in course if ($folder =~ /^default/) { - if ($allmaps{$url}) { + if ((ref($allmaps) eq 'HASH') && ($allmaps->{$url})) { return (&mt('Paste failed: only one instance of a particular published sequence or page is allowed within each course.')); } } } } - if ($url=~ m{/smppg$}) { - my $db_name = &Apache::lonsimplepage::get_db_name($url); - if ($db_name =~ /^smppage_/) { - #simple pages, need to copy the db contents to a new one. - my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); - my $now = time(); - $db_name =~ s{_\d*$ }{_$now}x; - my $dbresult=&Apache::lonnet::put($db_name,\%contents, - $coursedom,$coursenum); - if ($dbresult eq 'ok') { - $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + my $lockerrors; + if ($url=~ m{/(bulletinboard|smppg)$}) { + my $prefix = $1; + #need to copy the db contents to a new one, unless this is a move. + my %info = ( + src => $url, + cdom => $coursedom, + cnum => $coursenum, + ); + my (%lockerr,$msg); + unless ($env{'form.docs.markedcopy_options'} eq 'move') { + my ($newurl,$result,$errtext) = + &dbcopy(\%info,$coursedom,$coursenum,\%lockerr); + if ($result eq 'ok') { + $url = $newurl; $title=&mt('Copy of').' '.$title; } else { - return (&mt('Paste failed: An error occurred when copying the simple page.')); + if ($prefix eq 'smppg') { + $msg = &mt('Paste failed: An error occurred when copying the simple page.').' '.$errtext; + } elsif ($prefix eq 'bulletinboard') { + $msg = &mt('Paste failed: An error occurred when copying the bulletin board.').' '.$errtext; + } + return ($result,undef,[$msg],$lockerr{$prefix}); + } + if ($lockerr{$prefix}) { + $lockerrors = $lockerr{$prefix}; } - } + } } $title = &LONCAPA::map::qtunescape($title); my $ext='false'; @@ -1008,7 +1116,9 @@ sub do_paste_from_buffer { if ($newdocsdir eq '') { $newdocsdir = 'default'; } - if (($prefixchg) || ($srcdom ne $coursedom) || ($srcnum ne $coursenum)) { + if (($prefixchg) || + ($srcdom ne $coursedom) || ($srcnum ne $coursenum) || + ($env{'form.docs.markedcopy_options'} ne 'move')) { my $newpath = "$newprefix/$newdocsdir/$newidx/$rem"; $url = &Apache::lonclonecourse::writefile($env{'request.course.id'},$newpath, @@ -1026,16 +1136,34 @@ sub do_paste_from_buffer { } # Apply any changes to maps, or copy dependencies for uploaded HTML pages my ($result,$save_err); - $result = - &apply_fixups($folder,$is_map,$prefixchg,$coursedom,$coursenum,$oldurl, - $url,\%removefrommap,\%removeparam,\%rewrites,\%retitles, - \%copies,\%dbcopies,\%zombies,\%params,\%docmoves, - \%mapmoves,\%newsubdir,$errors,\%before,\%after); + my %updated = ( + rewrites => \%rewrites, + zombies => \%zombies, + removefrommap => \%removefrommap, + removeparam => \%removeparam, + dbcopies => \%dbcopies, + retitles => \%retitles, + ); + my %info = ( + newsubdir => \%newsubdir, + params => \%params, + before => \%before, + after => \%after, + ); + my %moves = ( + copies => \%copies, + docmoves => \%docmoves, + mapmoves => \%mapmoves, + ); + ($result,my $msgsarray,my $lockerror) = + &apply_fixups($folder,$is_map,$coursedom,$coursenum,$errors, + \%updated,\%info,\%moves,$prefixchg,$oldurl,$url,'paste'); + $lockerrors .= $lockerror; if ($result eq 'ok') { if ($is_map) { my ($errtext,$fatal) = &mapread($coursenum,$coursedom, $folder.'.'.$container); - return $errtext if ($fatal); + return ($errtext,$save_err,$msgsarray,$lockerrors) if ($fatal); if ($#LONCAPA::map::order<1) { my $idx=&LONCAPA::map::getresidx(); @@ -1066,13 +1194,13 @@ sub do_paste_from_buffer { $save_err = $errtext; } } - + if ($env{'form.docs.markedcopy_options'} eq 'move') { &Apache::lonnet::delenv('docs.markedcopy'); &Apache::lonnet::delenv('docs.markedcopy_nested'); &Apache::lonnet::delenv('docs.markedcopy_nestednames'); } - return ($result,$save_err); + return ($result,$save_err,$msgsarray,$lockerrors); } sub get_newmap_url { @@ -1136,20 +1264,96 @@ sub get_newmap_url { } sub dbcopy { - my ($url,$coursedom,$coursenum) = @_; - if ($url=~ m{/smppg$}) { - my $db_name = &Apache::lonsimplepage::get_db_name($url); - if ($db_name =~ /^smppage_/) { - #simple pages, need to copy the db contents to a new one. - my %contents=&Apache::lonnet::dump($db_name,$coursedom,$coursenum); - my $now = time(); - $db_name =~ s{_\d*$ }{_$now}x; - my $result=&Apache::lonnet::put($db_name,\%contents, - $coursedom,$coursenum); - $url =~ s{/(\d*)/smppg$ }{/$now/smppg}x; + my ($dbref,$coursedom,$coursenum,$lockerrorsref) = @_; + my ($url,$result,$errtext); + my $url = $dbref->{'src'}; + if (ref($dbref) eq 'HASH') { + if ($url =~ m{/(smppg|bulletinboard)$}) { + my $prefix = $1; + if (($dbref->{'cdom'} =~ /^$match_domain$/) && + ($dbref->{'cnum'} =~ /^$match_courseid$/)) { + my $db_name; + my $marker = (split(m{/},$url))[4]; + $marker=~s/\D//g; + if ($dbref->{'src'} =~ m{/smppg$}) { + $db_name = + &Apache::lonsimplepage::get_db_name($url,$marker, + $dbref->{'cdom'}, + $dbref->{'cnum'}); + } else { + $db_name = 'bulletinpage_'.$marker; + } + my ($suffix,$freedlock,$error) = + &Apache::lonnet::get_timebased_id($prefix,'num','templated', + $coursedom,$coursenum, + 'concat'); + if (!$suffix) { + if ($prefix eq 'smppg') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a simple page [_1].',$url); + } else { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix when copying a bulletin board [_1].',$url); + } + if ($error) { + $errtext .= '
'.$error; + } + } else { + #need to copy the db contents to a new one. + my %contents=&Apache::lonnet::dump($db_name, + $dbref->{'cdom'}, + $dbref->{'cnum'}); + if (exists($contents{'uploaded.photourl'})) { + my $photo = $contents{'uploaded.photourl'}; + my ($subdir,$fname) = + ($photo =~ m{^/uploaded/$match_domain/$match_courseid/+(bulletin|simplepage)/(?:|\d+/)([^/]+)$}); + my $newphoto; + if ($fname ne '') { + my $content = &Apache::lonnet::getfile($photo); + unless ($content eq '-1') { + $env{'form.'.$suffix.'.photourl'} = $content; + $newphoto = + &Apache::lonnet::finishuserfileupload($coursenum,$coursedom,$suffix.'.photourl',"$subdir/$suffix/$fname"); + delete($env{'form.'.$suffix.'.photourl'}); + } + } + if ($newphoto =~ m{^/uploaded/}) { + $contents{'uploaded.photourl'} = $newphoto; + } + } + $db_name =~ s{_\d*$ }{_$suffix}x; + $result=&Apache::lonnet::put($db_name,\%contents, + $coursedom,$coursenum); + if ($result eq 'ok') { + $url =~ s{/(\d*)/(smppg|bulletinboard)$}{/$suffix/$2}x; + } + } + if (($freedlock ne 'ok') && (ref($lockerrorsref) eq 'HASH')) { + $lockerrorsref->{$prefix} = + '
'. + &mt('There was a problem removing a lockfile.'); + if ($prefix eq 'smppg') { + $lockerrorsref->{$prefix} .= + &mt('This will prevent creation of additional simple pages in this course.'); + } else { + $lockerrorsref->{$prefix} .= &mt('This will prevent creation of additional bulletin boards in this course.'); + } + $lockerrorsref->{$prefix} .= &mt('Please contact the domain coordinator for your LON-CAPA domain.').'
'; + } + } + } elsif ($url =~ m{/syllabus$}) { + if (($dbref->{'cdom'} =~ /^$match_domain$/) && + ($dbref->{'cnum'} =~ /^$match_courseid$/)) { + if (($dbref->{'cdom'} ne $coursedom) || + ($dbref->{'cnum'} ne $coursenum)) { + my %contents=&Apache::lonnet::dump('syllabus', + $dbref->{'cdom'}, + $dbref->{'cnum'}); + $result=&Apache::lonnet::put('syllabus',\%contents, + $coursedom,$coursenum); + } + } } } - return $url; + return ($url,$result,$errtext); } sub uniqueness_check { @@ -1190,7 +1394,7 @@ sub contained_map_check { $titles->{$url}{$token->[2]->{'id'}} = $token->[2]->{'title'}; } else { if ($allmaps->{$ressrc}) { - $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc; + $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc; } elsif (ref($addedmaps->{$ressrc}) eq 'ARRAY') { $removefrommap->{$url}{$token->[2]->{'id'}} = $ressrc; } else { @@ -1214,18 +1418,10 @@ sub contained_map_check { return; } -sub reinit_role { - my ($cdom,$cnum,$chome) = @_; - my ($furl,$ferr) = &Apache::lonuserstate::readmap("$cdom/$cnum"); - unless ($ferr) { - &Apache::loncommon::update_content_constraints($cdom,$cnum,$chome,$cdom.'_'.$cnum); - } - return; -} - sub url_paste_fixups { - my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$allmaps,$rewrites,$retitles,$copies, - $dbcopies,$zombies,$params,$mapmoves,$mapchanges,$tomove,$newsubdir,$newurls) = @_; + my ($oldurl,$folder,$prefixchg,$cdom,$cnum,$fromcdom,$fromcnum,$allmaps, + $rewrites,$retitles,$copies,$dbcopies,$zombies,$params,$mapmoves, + $mapchanges,$tomove,$newsubdir,$newurls) = @_; my $checktitle; if (($prefixchg) && ($oldurl =~ m{^/uploaded/$match_domain/$match_courseid/supplemental})) { @@ -1252,13 +1448,13 @@ sub url_paste_fixups { my $title = $token->[2]->{'title'}; if ($checktitle) { if ($title =~ m{\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) { - $retitles->{$oldurl}{$ressrc} = $id; + $retitles->{$oldurl}{$id} = $ressrc; } } next if ($token->[2]->{'type'} eq 'external'); if ($token->[2]->{'type'} eq 'zombie') { next if ($skip); - $zombies->{$oldurl}{$ressrc} = $id; + $zombies->{$oldurl}{$id} = $ressrc; $changed = 1; } elsif ($ressrc =~ m{^/uploaded/($match_domain)/($match_courseid)/(.+)$}) { my $srcdom = $1; @@ -1270,10 +1466,11 @@ sub url_paste_fixups { my $prefix = $1; $mapname = $prefix.$2; if ($tomove->{$mapname}) { - &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps, - $rewrites,$retitles,$copies,$dbcopies,$zombies, - $params,$mapmoves,$mapchanges,$tomove,$newsubdir, - $newurls); + &url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum, + $srcdom,$srcnum,$allmaps,$rewrites, + $retitles,$copies,$dbcopies,$zombies, + $params,$mapmoves,$mapchanges,$tomove, + $newsubdir,$newurls); next; } else { ($newurl,my $error) = @@ -1291,28 +1488,39 @@ sub url_paste_fixups { ($mapchanges->{$oldurl}) || (($newurl ne '') && ($newurl ne $oldurl))) { if ($rem =~ /^(default|supplemental)(_?\d*).(sequence|page)$/) { - $rewrites->{$oldurl}{$ressrc} = $id; + $rewrites->{$oldurl}{$id} = $ressrc; $mapchanges->{$ressrc} = 1; - unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom,$cnum,$allmaps, - $rewrites,$retitles,$copies,$dbcopies,$zombies, - $params,$mapmoves,$mapchanges,$tomove,$newsubdir, - $newurls)) { + unless (&url_paste_fixups($ressrc,$folder,$prefixchg,$cdom, + $cnum,$srcdom,$srcnum,$allmaps, + $rewrites,$retitles,$copies,$dbcopies, + $zombies,$params,$mapmoves,$mapchanges, + $tomove,$newsubdir,$newurls)) { $mapmoves->{$ressrc} = 1; } $changed = 1; } else { - $rewrites->{$oldurl}{$ressrc} = $id; + $rewrites->{$oldurl}{$id} = $ressrc; $copies->{$oldurl}{$ressrc} = $id; $changed = 1; } } - } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/(.+)$}) { - next if ($skip); + } elsif ($ressrc =~ m{^/adm/($match_domain)/($match_courseid)/.+$}) { + next if ($skip); my $srcdom = $1; my $srcnum = $2; if (($srcdom ne $cdom) || ($srcnum ne $cnum)) { - $rewrites->{$oldurl}{$ressrc} = $id; - $dbcopies->{$oldurl}{$ressrc} = $id; + $rewrites->{$oldurl}{$id} = $ressrc; + $dbcopies->{$oldurl}{$id}{'src'} = $ressrc; + $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom; + $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum; + $changed = 1; + } + } elsif ($ressrc =~ m{^/adm/$match_domain/$match_username/\d+/(smppg|bulletinboard)$}) { + if (($fromcdom ne $cdom) || ($fromcnum ne $cnum) || + ($env{'form.docs.markedcopy_options'} ne 'move')) { + $dbcopies->{$oldurl}{$id}{'src'} = $ressrc; + $dbcopies->{$oldurl}{$id}{'cdom'} = $fromcdom; + $dbcopies->{$oldurl}{$id}{'cnum'} = $fromcnum; $changed = 1; } } elsif ($ressrc =~ m{^/public/($match_domain)/($match_courseid)/(.+)$}) { @@ -1320,8 +1528,9 @@ sub url_paste_fixups { my $srcdom = $1; my $srcnum = $2; if (($srcdom ne $cdom) || ($srcnum ne $cnum)) { - $rewrites->{$oldurl}{$ressrc} = $id; - $dbcopies->{$oldurl}{$ressrc} = $id; + $dbcopies->{$oldurl}{$id}{'src'} = $ressrc; + $dbcopies->{$oldurl}{$id}{'cdom'} = $srcdom; + $dbcopies->{$oldurl}{$id}{'cnum'} = $srcnum; $changed = 1; } } @@ -1341,24 +1550,73 @@ sub url_paste_fixups { } sub apply_fixups { - my ($folder,$is_map,$prefixchg,$cdom,$cnum,$oldurl,$url,$removefrommap, - $removeparam,$rewrites,$retitles,$copies,$dbcopies,$zombies,$params, - $docmoves,$mapmoves,$newsubdir,$errors,$before,$after) = @_; - foreach my $key (keys(%{$copies}),keys(%{$docmoves})) { + my ($folder,$is_map,$cdom,$cnum,$errors,$updated,$info,$moves,$prefixchg, + $oldurl,$url,$caller) = @_; + my (%rewrites,%zombies,%removefrommap,%removeparam,%dbcopies,%retitles, + %params,%newsubdir,%before,%after,%copies,%docmoves,%mapmoves,@msgs, + %lockerrors,$lockmsg); + if (ref($updated) eq 'HASH') { + if (ref($updated->{'rewrites'}) eq 'HASH') { + %rewrites = %{$updated->{'rewrites'}}; + } + if (ref($updated->{'zombies'}) eq 'HASH') { + %zombies = %{$updated->{'zombies'}}; + } + if (ref($updated->{'removefrommap'}) eq 'HASH') { + %removefrommap = %{$updated->{'removefrommap'}}; + } + if (ref($updated->{'removeparam'}) eq 'HASH') { + %removeparam = %{$updated->{'removeparam'}}; + } + if (ref($updated->{'dbcopies'}) eq 'HASH') { + %dbcopies = %{$updated->{'dbcopies'}}; + } + if (ref($updated->{'retitles'}) eq 'HASH') { + %retitles = %{$updated->{'retitles'}}; + } + } + if (ref($info) eq 'HASH') { + if (ref($info->{'newsubdir'}) eq 'HASH') { + %newsubdir = %{$info->{'newsubdir'}}; + } + if (ref($info->{'params'}) eq 'HASH') { + %params = %{$info->{'params'}}; + } + if (ref($info->{'before'}) eq 'HASH') { + %before = %{$info->{'before'}}; + } + if (ref($info->{'after'}) eq 'HASH') { + %after = %{$info->{'after'}}; + } + } + if (ref($moves) eq 'HASH') { + if (ref($moves->{'copies'}) eq 'HASH') { + %copies = %{$moves->{'copies'}}; + } + if (ref($moves->{'docmoves'}) eq 'HASH') { + %docmoves = %{$moves->{'docmoves'}}; + } + if (ref($moves->{'mapmoves'}) eq 'HASH') { + %mapmoves = %{$moves->{'mapmoves'}}; + } + } + foreach my $key (keys(%copies),keys(%docmoves)) { my @allcopies; - if (ref($copies->{$key}) eq 'HASH') { - my %added; - foreach my $innerkey (keys(%{$copies->{$key}})) { - if (($innerkey ne '') && (!$added{$innerkey})) { - push(@allcopies,$innerkey); - $added{$innerkey} = 1; + if (exists($copies{$key})) { + if (ref($copies{$key}) eq 'HASH') { + my %added; + foreach my $innerkey (keys(%{$copies{$key}})) { + if (($innerkey ne '') && (!$added{$innerkey})) { + push(@allcopies,$innerkey); + $added{$innerkey} = 1; + } } + undef(%added); } - undef(%added); } if ($key eq $oldurl) { - if ((exists($docmoves->{$key}))) { - unless (grep(/^\Q$oldurl\E/,@allcopies)) { + if ((exists($docmoves{$key}))) { + unless (grep(/^\Q$oldurl\E$/,@allcopies)) { push(@allcopies,$oldurl); } } @@ -1371,16 +1629,16 @@ sub apply_fixups { my $content = &Apache::lonnet::getfile($item); unless ($content eq '-1') { my $storefn; - if (($key eq $oldurl) && (ref($docmoves) eq 'HASH') && (exists($docmoves->{$key}))) { - $storefn = $docmoves->{$key}; + if (($key eq $oldurl) && (exists($docmoves{$key}))) { + $storefn = $docmoves{$key}; } else { $storefn = $relpath; $storefn =~s{^/uploaded/$match_domain/$match_courseid/}{}; - if ($prefixchg) { - $storefn =~ s/^\Q$before->{'doc'}\E/$after->{'doc'}/; + if ($prefixchg && $before{'doc'} && $after{'doc'}) { + $storefn =~ s/^\Q$before{'doc'}\E/$after{'doc'}/; } - if ($newsubdir->{$key}) { - $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir->{$key}#; + if ($newsubdir{$key}) { + $storefn =~ s#^(docs|supplemental)/\Q$oldsubdir\E/#$1/$newsubdir{$key}/#; } } ©_dependencies($item,$storefn,$relpath,$errors,\$content); @@ -1388,7 +1646,7 @@ sub apply_fixups { &Apache::lonclonecourse::writefile($env{'request.course.id'}, $storefn.$fname,$content); if ($copyurl eq '/adm/notfound.html') { - if ((ref($docmoves) eq 'HASH') && (exists($docmoves->{$oldurl}))) { + if (exists($docmoves{$oldurl})) { return &mt('Paste failed: an error occurred copying the file.'); } elsif (ref($errors) eq 'HASH') { $errors->{$item} = 1; @@ -1399,14 +1657,14 @@ sub apply_fixups { } } } - foreach my $key (keys(%{$mapmoves})) { + foreach my $key (keys(%mapmoves)) { my $storefn=$key; $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; - if ($prefixchg) { - $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/; + if ($prefixchg && $before{'map'} && $after{'map'}) { + $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/; } - if ($newsubdir->{$key}) { - $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/; + if ($newsubdir{$key}) { + $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; } my $mapcontent = &Apache::lonnet::getfile($key); if ($mapcontent eq '-1') { @@ -1426,105 +1684,106 @@ sub apply_fixups { } my %updates; if ($is_map) { - foreach my $key (keys(%{$rewrites})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$zombies})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$removefrommap})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$removeparam})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$dbcopies})) { - $updates{$key} = 1; - } - foreach my $key (keys(%{$retitles})) { - $updates{$key} = 1; + if (ref($updated) eq 'HASH') { + foreach my $type (keys(%{$updated})) { + if (ref($updated->{$type}) eq 'HASH') { + foreach my $key (keys(%{$updated->{$type}})) { + $updates{$key} = 1; + } + } + } } foreach my $key (keys(%updates)) { my (%torewrite,%toretitle,%toremove,%remparam,%currparam,%zombie,%newdb); - if (ref($rewrites->{$key}) eq 'HASH') { - %torewrite = %{$rewrites->{$key}}; - } - if (ref($retitles->{$key}) eq 'HASH') { - %toretitle = %{$retitles->{$key}}; + if (ref($rewrites{$key}) eq 'HASH') { + %torewrite = %{$rewrites{$key}}; } - if (ref($removefrommap->{$key}) eq 'HASH') { - %toremove = %{$removefrommap->{$key}}; + if (ref($retitles{$key}) eq 'HASH') { + %toretitle = %{$retitles{$key}}; } - if (ref($removeparam->{$key}) eq 'HASH') { - %remparam = %{$removeparam->{$key}}; + if (ref($removefrommap{$key}) eq 'HASH') { + %toremove = %{$removefrommap{$key}}; } - if (ref($zombies->{$key}) eq 'HASH') { - %zombie = %{$zombies->{$key}}; - } - if (ref($dbcopies->{$key}) eq 'HASH') { - foreach my $item (keys(%{$dbcopies->{$key}})) { - $newdb{$item} = &dbcopy($item); + if (ref($removeparam{$key}) eq 'HASH') { + %remparam = %{$removeparam{$key}}; + } + if (ref($zombies{$key}) eq 'HASH') { + %zombie = %{$zombies{$key}}; + } + if (ref($dbcopies{$key}) eq 'HASH') { + foreach my $idx (keys(%{$dbcopies{$key}})) { + if (ref($dbcopies{$key}{$idx}) eq 'HASH') { + my ($newurl,$result,$errtext) = + &dbcopy($dbcopies{$key}{$idx},$cdom,$cnum,\%lockerrors); + if ($result eq 'ok') { + $newdb{$idx} = $newurl; + } elsif (ref($errors) eq 'HASH') { + $errors->{$key} = 1; + } + push(@msgs,$errtext); + } } } - if (ref($params->{$key}) eq 'HASH') { - %currparam = %{$params->{$key}}; + if (ref($params{$key}) eq 'HASH') { + %currparam = %{$params{$key}}; } my ($errtext,$fatal) = &LONCAPA::map::mapread($key); if ($fatal) { - return $errtext; + return ($errtext); } for (my $i=0; $i<@LONCAPA::map::zombies; $i++) { if (defined($LONCAPA::map::zombies[$i])) { my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::zombies[$i]); - if ($zombie{$src} eq $i) { + if ($zombie{$i} eq $src) { undef($LONCAPA::map::zombies[$i]); } } } - for (my $i=0; $i<@LONCAPA::map::resources; $i++) { - if (defined($LONCAPA::map::resources[$i])) { + for (my $i=0; $i<@LONCAPA::map::order; $i++) { + my $idx = $LONCAPA::map::order[$i]; + if (defined($LONCAPA::map::resources[$idx])) { my $changed; - my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$i]); - if ($toremove{$src} eq $i) { + my ($title,$src,$ext,$type)=split(/\:/,$LONCAPA::map::resources[$idx]); + if ((exists($toremove{$idx})) && ($toremove{$idx} eq $src)) { splice(@LONCAPA::map::order,$i,1); - if (ref($currparam{$i}) eq 'ARRAY') { - foreach my $name (@{$currparam{$i}}) { - &LONCAPA::map::delparameter($i,'parameter_'.$name); + if (ref($currparam{$idx}) eq 'ARRAY') { + foreach my $name (@{$currparam{$idx}}) { + &LONCAPA::map::delparameter($idx,'parameter_'.$name); } } next; } my $origsrc = $src; - if ((exists($toretitle{$src})) && ($toretitle{$src} eq $i)) { + if ((exists($toretitle{$idx})) && ($toretitle{$idx} eq $src)) { if ($title =~ m{^\d+\Q___&&&___\E$match_username\Q___&&&___\E$match_domain\Q___&&&___\E(.+)$}) { $changed = 1; } } - if ((exists($torewrite{$src})) && ($torewrite{$src} eq $i)) { + if ((exists($torewrite{$idx})) && ($torewrite{$idx} eq $src)) { $src =~ s{^/(uploaded|adm|public)/$match_domain/$match_courseid/}{/$1/$cdom/$cnum/}; if ($origsrc =~ m{^/uploaded/}) { - if ($prefixchg) { + if ($prefixchg && $before{'map'} && $after{'map'}) { if ($src =~ /\.(page|sequence)$/) { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'map'}\E#$1$after->{'map'}#; + $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'map'}\E#$1$after{'map'}#; } else { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before->{'doc'}\E#$1$after->{'doc'}#; + $src =~ s#^(/uploaded/$match_domain/$match_courseid/)\Q$before{'doc'}\E#$1$after{'doc'}#; } } - if ($newsubdir->{$origsrc}) { - if ($src =~ /\.(page|sequence)$/) { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir->{$origsrc}#; - } else { - $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir->{$origsrc}#; + if ($origsrc =~ /\.(page|sequence)$/) { + if ($newsubdir{$origsrc}) { + $src =~ s#^(/uploaded/$match_domain/$match_courseid/(?:default|supplemental)_)(\d+)#$1$newsubdir{$origsrc}#; } + } elsif ($newsubdir{$key}) { + $src =~ s#^(/uploaded/$match_domain/$match_courseid/\w+/)(\d+)#$1$newsubdir{$key}#; } } $changed = 1; - } elsif ($newdb{$src} ne '') { - $src = $newdb{$src}; + } elsif ($newdb{$idx} ne '') { + $src = $newdb{$idx}; $changed = 1; } if ($changed) { - $LONCAPA::map::resources[$i] = join(':',($title,$src,$ext,$type)); + $LONCAPA::map::resources[$idx] = join(':',($title,$src,$ext,$type)); } } } @@ -1535,6 +1794,9 @@ sub apply_fixups { } } } + if (values(%lockerrors) > 0) { + $lockmsg = join('
',values(%lockerrors)); + } my $storefn; if ($key eq $oldurl) { $storefn = $url; @@ -1542,25 +1804,27 @@ sub apply_fixups { } else { $storefn = $key; $storefn=~s{^/uploaded/$match_domain/$match_courseid/}{}; - if ($prefixchg) { - $storefn =~ s/^\Q$before->{'map'}\E/$after->{'map'}/; + if ($prefixchg && $before{'map'} && $after{'map'}) { + $storefn =~ s/^\Q$before{'map'}\E/$after{'map'}/; } - if ($newsubdir->{$key}) { - $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir->{$key}/; + if ($newsubdir{$key}) { + $storefn =~ s/^((?:default|supplemental)_)(\d+)/$1$newsubdir{$key}/; } } my $report; if ($folder !~ /^supplemental/) { $report = 1; } - my ($outtext,$errtext) = + (my $outtext,$errtext) = &LONCAPA::map::storemap("/uploaded/$cdom/$cnum/$storefn",1,$report); if ($errtext) { - return &mt('Paste failed: an error occurred saving the folder or page.'); + if ($caller eq 'paste') { + return (&mt('Paste failed: an error occurred saving the folder or page.')); + } } } } - return 'ok'; + return ('ok',\@msgs,$lockmsg); } sub copy_dependencies { @@ -1625,23 +1889,93 @@ my %parameter_type = ( 'randompick' my $valid_parameters_re = join('|',keys(%parameter_type)); # set parameters sub update_parameter { - - return 0 if ($env{'form.changeparms'} !~ /^($valid_parameters_re)$/); - - my $which = $env{'form.changeparms'}; - my $idx = $env{'form.setparms'}; - if ($env{'form.'.$which.'_'.$idx}) { - my $value = ($which eq 'randompick') ? $env{'form.'.$which.'_'.$idx} - : 'yes'; - &LONCAPA::map::storeparameter($idx, 'parameter_'.$which, $value, - $parameter_type{$which}); - &remember_parms($idx,$which,'set',$value); + if ($env{'form.changeparms'} eq 'all') { + my (@allidx,@allmapidx,%allchecked,%currchecked); + %allchecked = ( + 'hiddenresource' => {}, + 'encrypturl' => {}, + 'randompick' => {}, + 'randomorder' => {}, + ); + foreach my $which (keys(%allchecked)) { + $env{'form.all'.$which} =~ s/,$//; + if ($which eq 'randompick') { + foreach my $item (split(/,/,$env{'form.all'.$which})) { + my ($res,$value) = split(/:/,$item); + if ($value =~ /^\d+$/) { + $allchecked{$which}{$res} = $value; + } + } + } else { + map { $allchecked{$which}{$_} = 1; } split(/,/,$env{'form.all'.$which}); + } + } + my $haschanges = 0; + foreach my $res (@LONCAPA::map::order) { + my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]); + $name=&LONCAPA::map::qtescape($name); + $url=&LONCAPA::map::qtescape($url); + next unless ($name && $url); + my $is_map; + if ($url =~ m{/uploaded/.+\.(page|sequence)$}) { + $is_map = 1; + } + foreach my $which (keys(%allchecked)) { + if (($which eq 'randompick' || $which eq 'randomorder')) { + next if (!$is_map); + } + my $oldvalue = 0; + my $newvalue = 0; + if ($allchecked{$which}{$res}) { + $newvalue = $allchecked{$which}{$res}; + } + my $current = (&LONCAPA::map::getparameter($res,'parameter_'.$which))[0]; + if ($which eq 'randompick') { + if ($current =~ /^(\d+)$/) { + $oldvalue = $1; + } + } else { + if ($current =~ /^yes$/i) { + $oldvalue = 1; + } + } + if ($oldvalue ne $newvalue) { + $haschanges = 1; + if ($newvalue) { + my $storeval = 'yes'; + if ($which eq 'randompick') { + $storeval = $newvalue; + } + &LONCAPA::map::storeparameter($res,'parameter_'.$which, + $storeval, + $parameter_type{$which}); + &remember_parms($res,$which,'set',$storeval); + } elsif ($oldvalue) { + &LONCAPA::map::delparameter($res,'parameter_'.$which); + &remember_parms($res,$which,'del'); + } + } + } + } + return $haschanges; } else { - &LONCAPA::map::delparameter($idx,'parameter_'.$which); + return 0 if ($env{'form.changeparms'} !~ /^($valid_parameters_re)$/); + + my $which = $env{'form.changeparms'}; + my $idx = $env{'form.setparms'}; + if ($env{'form.'.$which.'_'.$idx}) { + my $value = ($which eq 'randompick') ? $env{'form.rpicknum_'.$idx} + : 'yes'; + &LONCAPA::map::storeparameter($idx, 'parameter_'.$which, $value, + $parameter_type{$which}); + &remember_parms($idx,$which,'set',$value); + } else { + &LONCAPA::map::delparameter($idx,'parameter_'.$which); - &remember_parms($idx,$which,'del'); + &remember_parms($idx,$which,'del'); + } + return 1; } - return 1; } @@ -1692,16 +2026,23 @@ sub handle_edit_cmd { sub editor { my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$crstype, $supplementalflag,$orderhash,$iconpath,$pathitem)=@_; - my $container= ($env{'form.pagepath'}) ? 'page' - : 'sequence'; - my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order); + my ($randompick,$ishidden,$isencrypted,$plain,$is_random_order,$container); if ($allowed) { - (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order) = + (my $breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain, + $is_random_order,$container) = &Apache::lonhtmlcommon::docs_breadcrumbs($allowed,$crstype,1); $r->print($breadcrumbtrail); + } elsif ($env{'form.folderpath'} =~ /\:1$/) { + $container = 'page'; + } else { + $container = 'sequence'; } - my $jumpto = "uploaded/$coursedom/$coursenum/$folder.$container"; + my $jumpto; + + unless ($supplementalflag) { + $jumpto = "'uploaded/$coursedom/$coursenum/$folder.$container'"; + } unless ($allowed) { $randompick = -1; @@ -1741,9 +2082,22 @@ sub editor { if ($env{'form.pastemarked'}) { my %paste_errors; - my ($paste_res,$save_error) = + my ($paste_res,$save_error,$pastemsgarray,$lockerror) = &do_paste_from_buffer($coursenum,$coursedom,$folder,$container, \%paste_errors); + if (ref($pastemsgarray) eq 'ARRAY') { + if (@{$pastemsgarray} > 0) { + + $r->print('

'. + join('
',@{$pastemsgarray}). + '

'); + } + } + if ($lockerror) { + $r->print('

'. + $lockerror. + '

'); + } if ($save_error ne '') { return $save_error; } @@ -1777,10 +2131,10 @@ sub editor { foreach my $item (split(/\&/,$env{'form.importdetail'})) { if (defined($item)) { my ($name,$url,$residx)= - map {&unescape($_)} split(/\=/,$item); - if ($url=~ m{^\Q/uploaded/$coursedom/$coursenum/\E(default|supplemental)_new\.(sequence|page)$}) { - my ($suffix,$errortxt,$locknotfreed) = - &newmap_suffix($1,$2,$coursedom,$coursenum); + map { &unescape($_); } split(/\=/,$item); + if ($url =~ m{^\Q/uploaded/$coursedom/$coursenum/\E(default|supplemental)_new\.(sequence|page)$}) { + my ($suffix,$errortxt,$locknotfreed) = + &new_timebased_suffix($coursedom,$coursenum,'map',$1,$2); if ($locknotfreed) { $r->print($locknotfreed); } @@ -1789,13 +2143,45 @@ sub editor { } else { return $errortxt; } + } elsif ($url =~ m{^/adm/$match_domain/$match_username/new/(smppg|bulletinboard)$}) { + my $type = $1; + my ($suffix,$errortxt,$locknotfreed) = + &new_timebased_suffix($coursedom,$coursenum,$type); + if ($locknotfreed) { + $r->print($locknotfreed); + } + if ($suffix) { + $url =~ s{^(/adm/$match_domain/$match_username)/new}{$1/$suffix}; + } else { + return $errortxt; + } + } elsif ($url =~ m{^/uploaded/$coursedom/$coursenum/(docs|supplemental)/(default|\d+)/new.html$}) { + if ($supplementalflag) { + next unless ($1 eq 'supplemental'); + if ($folder eq 'supplemental') { + next unless ($2 eq 'default'); + } else { + next unless ($folder eq 'supplemental_'.$2); + } + } else { + next unless ($1 eq 'docs'); + if ($folder eq 'default') { + next unless ($2 eq 'default'); + } else { + next unless ($folder eq 'default_'.$2); + } + } } push(@imports, [$name, $url, $residx]); } } - ($errtext,$fatal)=&group_import($coursenum, $coursedom, $folder, - $container,'londocs',@imports); + ($errtext,$fatal,my $fixuperrors) = + &group_import($coursenum, $coursedom, $folder,$container, + 'londocs',@imports); return $errtext if ($fatal); + if ($fixuperrors) { + $r->print($fixuperrors); + } } # Loading a complete map if ($env{'form.loadmap'}) { @@ -1851,7 +2237,7 @@ sub editor { $r->print(''); } - my ($to_show,$output); + my ($to_show,$output,@allidx,@allmapidx); &Apache::loncommon::start_data_table_count(); #setup a row counter foreach my $res (@LONCAPA::map::order) { @@ -1860,15 +2246,29 @@ sub editor { $url=&LONCAPA::map::qtescape($url); unless ($name) { $name=(split(/\//,$url))[-1]; } unless ($name) { $idx++; next; } + push(@allidx,$res); + if ($url =~ m{/uploaded/.+\.(page|sequence)$}) { + push(@allmapidx,$res); + } $output .= &entryline($idx,$name,$url,$folder,$allowed,$res, $coursenum,$coursedom,$crstype, - $pathitem,$supplementalflag); + $pathitem,$supplementalflag,$container); $idx++; $shown++; } &Apache::loncommon::end_data_table_count(); if (($allowed) || ($supplementalflag && $folder eq 'supplemental')) { + my $toolslink = '
' + .'
' + .&Apache::loncommon::help_open_menu('Navigation Screen', + 'Navigation_Screen',undef,'RAT') + .''.&mt('Tools:').'

'; if ($shown) { if ($allowed) { $to_show = &Apache::loncommon::start_scrollbox('900px','880px','400px','contentscroll') @@ -1880,25 +2280,61 @@ sub editor { if ($folder !~ /^supplemental/) { $to_show .= ''.&mt('Settings').''; } - $to_show .= &Apache::loncommon::end_data_table_header_row() - .$output.' ' + $to_show .= &Apache::loncommon::end_data_table_header_row(); + if ($folder !~ /^supplemental/) { + my $idxlist = join(',',@allidx); + my $mapidxlist = join(',',@allmapidx); + if (@allidx > 0) { + my $path; + if ($env{'form.folderpath'}) { + $path = + &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); + } + $to_show .= + &Apache::loncommon::continue_data_table_row(). + ' '. + ''. + '
'. + ''.&mt('Select:').' '. + ''.(' 'x2).'
'. + ''. + + ''. + &Apache::loncommon::end_data_table_row(); + } + } + $to_show .= $output.' ' .&Apache::loncommon::end_data_table() .'
' .&Apache::loncommon::end_scrollbox(); } else { - $to_show = '' - .'
'.&Apache::loncommon::help_open_menu('Navigation Screen','Navigation_Screen',undef,'RAT') - .''.&mt('Tools:').'

' + $to_show .= $toolslink .&Apache::loncommon::start_data_table('LC_tableOfContent') .$output.' ' .&Apache::loncommon::end_data_table(); } } else { + if (!$allowed) { + $to_show .= $toolslink; + } $to_show .= &Apache::loncommon::start_scrollbox('400px','380px','200px','contentscroll') .'
' .&mt('Currently no documents.') @@ -1948,19 +2384,15 @@ sub process_file_upload { my $errtext=''; my $fatal=0; my $container='sequence'; - if ($env{'form.pagepath'}) { + if ($env{'form.folderpath'} =~ /:1$/) { $container='page'; } ($errtext,$fatal)= - &mapread($coursenum,$coursedom,$folder.'.'.$container); + &mapread($coursenum,$coursedom,$folder.'.'.$container); if ($#LONCAPA::map::order<1) { $LONCAPA::map::order[0]=1; $LONCAPA::map::resources[1]=''; } - if ($fatal) { - $$upload_output = '
'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'
'; - return; - } my $destination = 'docs/'; if ($folder =~ /^supplemental/) { $destination = 'supplemental/'; @@ -1970,6 +2402,10 @@ sub process_file_upload { } elsif ($folder =~ /^(default|supplemental)_(\d+)$/) { $destination .= $2.'/'; } + if ($fatal) { + $$upload_output = '
'.&mt('The uploaded file has not been stored as an error occurred reading the contents of the current folder.').'
'; + return; + } # this is for a course, not a user, so set context to coursedoc. my $newidx=&LONCAPA::map::getresidx(); $destination .= $newidx; @@ -2038,7 +2474,6 @@ sub process_file_upload { my $archiveurl = &HTML::Entities::encode($url,'<>&"'); my %archiveitems = ( folderpath => $env{'form.folderpath'}, - pagepath => $env{'form.pagepath'}, cmd => $nextphase, newidx => $newidx, position => $position, @@ -2093,16 +2528,14 @@ sub is_supplemental_title { sub entryline { my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom, - $crstype,$pathitem,$supplementalflag)=@_; - my ($foldertitle,$pagetitle,$renametitle); + $crstype,$pathitem,$supplementalflag,$container)=@_; + my ($foldertitle,$renametitle); if (&is_supplemental_title($title)) { ($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title); - $pagetitle = $foldertitle; } else { $title=&HTML::Entities::encode($title,'"<>&\''); $renametitle=$title; $foldertitle=$title; - $pagetitle=$title; } my $orderidx=$LONCAPA::map::order[$index]; @@ -2113,19 +2546,12 @@ sub entryline { my $line=&Apache::loncommon::start_data_table_row(); my ($form_start,$form_end,$form_common); # Edit commands - my ($container, $type, $esc_path, $path, $symb); + my ($esc_path, $path, $symb); if ($env{'form.folderpath'}) { - $type = 'folder'; - $container = 'sequence'; $esc_path=&escape($env{'form.folderpath'}); $path = &HTML::Entities::encode($env{'form.folderpath'},'<>&"'); # $htmlfoldername=&HTML::Entities::encode($env{'form.foldername'},'<>&"'); } - if ($env{'form.pagepath'}) { - $type = $container = 'page'; - $esc_path=&escape($env{'form.pagepath'}); - $path = &HTML::Entities::encode($env{'form.pagepath'},'<>&"'); - } my $isexternal; if ($residx) { my $currurl = $url; @@ -2142,7 +2568,7 @@ sub entryline { &Apache::lonnet::declutter($currurl)); } } - my %lt; + my ($renamelink,%lt); if ($allowed) { my $incindex=$index+1; my $selectbox=''; @@ -2239,7 +2665,7 @@ sub entryline { $nocopy=1; } } - my ($copylink,$cutlink,$removelink,$renamelink); + my ($copylink,$cutlink,$removelink); my $skip_confirm = 0; if ( $folder =~ /^supplemental/ || ($url =~ m{( /smppg$ @@ -2258,7 +2684,7 @@ sub entryline { ENDCOPY } else { $copylink=(<$lt{'cp'} +$lt{'cp'} ENDCOPY } if ($nocut) { @@ -2267,7 +2693,7 @@ ENDCOPY ENDCUT } else { $cutlink=(<$lt{'ct'} +$lt{'ct'} ENDCUT } if ($noremove) { @@ -2276,18 +2702,20 @@ ENDCUT ENDREM } else { $removelink=(<$lt{'rm'} +$lt{'rm'} ENDREM } - $renamelink=(<$lt{'rn'} + unless ($isexternal) { + $renamelink=(<$lt{'rn'} ENDREN + } $form_start = '
'; $form_common=(< - + + END @@ -2295,12 +2723,12 @@ END $line.=(<
- + $lt{'up'}
- + $lt{'dw'}
@@ -2313,7 +2741,6 @@ END $removelink -$renamelink $cutlink $copylink @@ -2325,22 +2752,18 @@ END my ($extension)=($url=~/\.(\w+)$/); my $uploaded=($url=~/^\/*uploaded\//); my $icon=&Apache::loncommon::icon($url); - my $isfolder=0; - my $ispage=0; - my $folderarg; - my $pagearg; - my $pagefile; + my $isfolder; + my $ispage; + my $containerarg; if ($uploaded) { if (($extension eq 'sequence') || ($extension eq 'page')) { $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/; - my $containerarg = $1; + $containerarg = $1; if ($extension eq 'sequence') { $icon=$iconpath.'navmap.folder.closed.gif'; - $folderarg=$containerarg; $isfolder=1; } else { $icon=$iconpath.'page.gif'; - $pagearg=$containerarg; $ispage=1; } if ($allowed) { @@ -2353,15 +2776,11 @@ END } } - my $editlink; + my ($editlink,$extresform); my $orig_url = $url; $orig_url=~s{http(:|:)//https(:|:)//}{https$2//}; $url=~s{^http(|s)(:|:)//}{/adm/wrapper/ext/}; if (!$supplementalflag && $residx && $symb) { - if ($container eq 'page') { - $url=&Apache::lonnet::clutter((&Apache::lonnet::decode_symb($symb))[2]); - $url.=(($url=~/\?/)?'&':'?').'symb='.&escape($symb); - } if ((!$isfolder) && (!$ispage)) { (undef,undef,$url)=&Apache::lonnet::decode_symb($symb); $url=&Apache::lonnet::clutter($url); @@ -2386,17 +2805,17 @@ END } } my ($rand_pick_text,$rand_order_text); - if ($isfolder || $extension eq 'sequence') { + if ($isfolder || $ispage || $extension eq 'sequence' || $extension eq 'page') { my $foldername=&escape($foldertitle); my $folderpath=$env{'form.folderpath'}; if ($folderpath) { $folderpath.='&' }; if (!$allowed && $supplementalflag) { - $folderpath.=$folderarg.'&'.$foldername; + $folderpath.=$containerarg.'&'.$foldername; $url.='folderpath='.&escape($folderpath); } else { # Append randompick number, hidden, and encrypted with ":" to foldername, # so it gets transferred between levels - $folderpath.=$folderarg.'&'.$foldername. + $folderpath.=$containerarg.'&'.$foldername. ':'.(&LONCAPA::map::getparameter($orderidx, 'parameter_randompick'))[0] .':'.((&LONCAPA::map::getparameter($orderidx, @@ -2404,7 +2823,8 @@ END .':'.((&LONCAPA::map::getparameter($orderidx, 'parameter_encrypturl'))[0]=~/^yes$/i) .':'.((&LONCAPA::map::getparameter($orderidx, - 'parameter_randomorder'))[0]=~/^yes$/i); + 'parameter_randomorder'))[0]=~/^yes$/i) + .':'.$ispage; $url.='folderpath='.&escape($folderpath); my $rpicknum = (&LONCAPA::map::getparameter($orderidx, 'parameter_randompick'))[0]; @@ -2412,21 +2832,24 @@ END if ($rpicknum) { $rpckchk = ' checked="checked"'; } - my $formname = 'edit_rpick_'.$orderidx; + my $formname = 'edit_randompick_'.$orderidx; $rand_pick_text = ''."\n". $form_common."\n". -''; +''; if ($rpicknum ne '') { $rand_pick_text .= ': '.$rpicknum.''; } - $rand_pick_text .= ''; + $rand_pick_text .= ''. + $form_end; my $ro_set= ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':''); + my $formname = 'edit_rorder_'.$orderidx; $rand_order_text = -$form_start. -$form_common.' -'; +'
'."\n". +$form_common."\n". +''. +$form_end; } } elsif ($supplementalflag && !$allowed) { $url .= ($url =~ /\?/) ? '&':'?'; @@ -2438,20 +2861,12 @@ $form_common.' $url .= '&idx='.$orderidx; } } - if ($ispage) { - my $pagename=&escape($pagetitle); - my $pagepath; - my $folderpath=$env{'form.folderpath'}; - if ($folderpath) { $pagepath = $folderpath.'&' }; - $pagepath.=$pagearg.'&'.$pagename; - $url.='pagepath='.&escape($pagepath). - '&pagesymb='.&escape($symb); - } + my ($tdalign,$tdwidth); if ($allowed) { my $fileloc = &Apache::lonnet::declutter(&Apache::lonnet::filelocation('',$orig_url)); if ($isexternal) { - $editlink = ' '. + ($editlink,$extresform) = &Apache::lonextresedit::extedit_form(0,$residx,$orig_url,$title,$pathitem); } elsif (!$isfolder && !$ispage) { my ($cfile,$home,$switchserver,$forceedit,$forceview) = @@ -2463,21 +2878,23 @@ $form_common.' $forceedit, undef,$symb, &escape($env{'form.folderpath'}), - $renametitle); + $renametitle,'','',1); if ($jscall) { - $editlink = ' '.&mt('Edit').''; + $editlink = ''.&mt('Edit').' '."\n"; } } } + $tdalign = ' align="right" valign="top"'; + $tdwidth = ' width="80%"'; } my $reinit; if ($crstype eq 'Community') { $reinit = &mt('(re-initialize community to access)'); } else { $reinit = &mt('(re-initialize course to access)'); - } - $line.=''; + } + $line.=''.$editlink.$renamelink; if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''; } elsif ($url) { @@ -2486,7 +2903,7 @@ $form_common.' } else { $line.=''; } - $line.=''; + $line.=''; if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) { $line.=''.$title.''; } elsif ($url) { @@ -2495,7 +2912,7 @@ $form_common.' } else { $line.=$title.' '.$reinit.''; } - $line.=$editlink.""; + $line.="$extresform"; $rand_pick_text = ' ' if ($rand_pick_text eq ''); $rand_order_text = ' ' if ($rand_order_text eq ''); if (($allowed) && ($folder!~/^supplemental/)) { @@ -2506,16 +2923,18 @@ $form_common.' ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i?' checked="checked"':''); my $hidtext= ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i?' checked="checked"':''); + my $formhidden = 'edit_hiddenresource_'.$orderidx; + my $formurlhidden = 'edit_encrypturl_'.$orderidx; $line.=(< - $form_start + $form_common - + $form_end
- $form_start + $form_common - + $form_end $rand_pick_text
@@ -2526,26 +2945,52 @@ ENDPARMS return $line; } -sub newmap_suffix { - my ($area,$container,$coursedom,$coursenum) = @_; - my ($prefix,$idtype,$errtext,$locknotfreed); - $prefix = 'docs'; - if ($area eq 'supplemental') { - $prefix = 'supp'; +sub new_timebased_suffix { + my ($coursedom,$coursenum,$type,$area,$container) = @_; + my ($prefix,$namespace,$idtype,$errtext,$locknotfreed); + if ($type eq 'map') { + $prefix = 'docs'; + if ($area eq 'supplemental') { + $prefix = 'supp'; + } + $prefix .= $container; + $namespace = 'uploadedmaps'; + } else { + $prefix = $type; + $namespace = 'templated'; } - $prefix .= $container; $idtype = 'concat'; my ($suffix,$freedlock,$error) = - &Apache::lonnet::get_timebased_id($prefix,'num','uploadedmaps', + &Apache::lonnet::get_timebased_id($prefix,'num',$namespace, $coursedom,$coursenum); if (!$suffix) { - $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.'); + if ($type eq 'map') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new folder/page.'); + } elsif ($type eq 'smppg') { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new simple page.'); + } else { + $errtext = &mt('Failed to acquire a unique timestamp-based suffix for the new bulletin board.'); + } if ($error) { $errtext .= '
'.$error; } } if ($freedlock ne 'ok') { - $locknotfreed = '
'.&mt('There was a problem removing a lockfile. This will prevent creation of additional folders or composite pages in this course. Please contact the domain coordinator for your LON-CAPA domain.').'
'; + $locknotfreed = + '
'. + &mt('There was a problem removing a lockfile.').' '; + if ($type eq 'map') { + &mt('This will prevent creation of additional folders or composite pages in this course.'); + } elsif ($type eq 'smppg') { + $locknotfreed .= + &mt('This will prevent creation of additional simple pages in this course.'); + } else { + $locknotfreed .= + &mt('This will prevent creation of additional bulletin boards in this course.'); + } + $locknotfreed .= + ' '.&mt('Please contact the domain coordinator for your LON-CAPA domain.'). + '
'; } return ($suffix,$errtext,$locknotfreed); } @@ -2645,7 +3090,7 @@ sub checkonthis { $r->print(''.&mt('connection down').''); } elsif ($result eq 'not_found') { unless ($url=~/\$/) { - $r->print(''.&mt('not found').''); + $r->print(''.&mt('not found').''); } else { $r->print(''.&mt('unable to verify variable URL').''); } @@ -2691,7 +3136,7 @@ sub list_symbs { $r->print(&Apache::loncommon::start_data_table_row(). ''.$res->compTitle().''. ''.$res->symb().''. - &Apache::loncommon::start_data_table_row()); + &Apache::loncommon::end_data_table_row()); $count ++; } if (!$count) { @@ -2701,6 +3146,7 @@ sub list_symbs { } $r->print(&Apache::loncommon::end_data_table()); } + $r->print(&endContentScreen()); } @@ -2731,6 +3177,7 @@ sub verifycontent { } &untiehash(); $r->print('

'.&mt('Done').'

'); + $r->print(&endContentScreen()); } @@ -2810,7 +3257,7 @@ sub checkversions { if ($env{'form.timerange'} eq 'all') { # show all documents $header=&mt('All Documents in '.$crstype); - $allsel=1; + $allsel=' selected="selected"'; foreach my $key (keys(%hash)) { if ($key=~/^ids\_(\/res\/.+)$/) { my $src=$1; @@ -2831,19 +3278,19 @@ sub checkversions { .&mt('seconds'); if ($env{'form.timerange'}==-1) { $seltext='since start of course'; - $startsel='selected'; + $startsel=' selected="selected"'; $env{'form.timerange'}=time; } $starttime=time-$env{'form.timerange'}; if ($env{'form.timerange'}==2592000) { $seltext=&mt('during the last month').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; - $monthsel='selected'; + $monthsel=' selected="selected"'; } elsif ($env{'form.timerange'}==604800) { $seltext=&mt('during the last week').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; - $weeksel='selected'; + $weeksel=' selected="selected"'; } elsif ($env{'form.timerange'}==86400) { $seltext=&mt('since yesterday').' ('.&Apache::lonlocal::locallocaltime($starttime).')'; - $daysel='selected'; + $daysel=' selected="selected"'; } $header=&mt('Content changed').' '.$seltext; } else { @@ -2881,11 +3328,11 @@ sub checkversions {
$lt{'cd'}
@@ -2901,111 +3348,93 @@ $lt{'sc'}: - ENDHEADERS #number of columns for version history - my $num_ver_col = 1; $r->print( - &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). - ''. - "". - "". - "". - ''. - ''); + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''. + "". + "". + "". + ''. + &Apache::loncommon::end_data_table_header_row() + ); foreach my $key (sort(keys(%changes))) { #excludes not versionable problems from resource version history: - if ($changes{$key}>$starttime && $key !~ /^\/res\/lib\/templates/) { - my ($root,$extension)=($key=~/^(.*)\.(\w+)$/); - my $currentversion=&Apache::lonnet::getversion($key); - if ($currentversion<0) { - $currentversion=''.&mt('Could not be determined.').''; - } - my $linkurl=&Apache::lonnet::clutter($key); + next unless ($changes{$key}>$starttime && $key !~ /^\/res\/lib\/templates/); + my ($root,$extension)=($key=~/^(.*)\.(\w+)$/); + my $currentversion=&Apache::lonnet::getversion($key); + if ($currentversion<0) { + $currentversion=''.&mt('Could not be determined.').''; + } + my $linkurl=&Apache::lonnet::clutter($key); $r->print( - &Apache::loncommon::end_data_table_header_row(). &Apache::loncommon::start_data_table_row(). - ''. - ''. - ''); - if ($cols_output != $num_ver_col) { - $r->print(''); + # List all available versions + $r->print(''.&Apache::loncommon::end_data_table_row()); } - $r->print(''.&Apache::loncommon::end_data_table_row(). - &Apache::loncommon::end_data_table(). - ''); + $r->print( + &Apache::loncommon::end_data_table(). + ''. + '' + ); &untiehash(); + $r->print(&endContentScreen()); } sub mark_hash_old { @@ -3037,11 +3466,6 @@ sub changewarning { my $pathvar='folderpath'; my $path=&escape($env{'form.folderpath'}); if (!defined($url)) { - if (defined($env{'form.pagepath'})) { - $pathvar='pagepath'; - $path=&escape($env{'form.pagepath'}); - $path.='&pagesymb='.&escape($env{'form.pagesymb'}); - } $url='/adm/coursedocs?'.$pathvar.'='.$path; } my $course_type = &Apache::loncommon::course_type(); @@ -3172,8 +3596,9 @@ sub handler { 'Docs_About_My_Personal_Info,Docs_Editing_Templated_Pages'); $help{'Group Portfolio'} = &Apache::loncommon::help_open_topic('Docs_About_Group_Files'); $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching'); - - + $help{'Course Roster'} = &Apache::loncommon::help_open_topic('Docs_Course_Roster'); + $help{'Web Page'} = &Apache::loncommon::help_open_topic('Docs_Web_Page'); + my $allowed; # URI is /adm/supplemental when viewing supplemental docs in non-edit mode. unless ($r->uri eq '/adm/supplemental') { @@ -3215,8 +3640,8 @@ sub handler { # Get the parameters that may be needed # &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['folderpath','pagepath', - 'pagesymb','forcesupplement','forcestandard', + ['folderpath', + 'forcesupplement','forcestandard', 'tools','symb','command','supppath']); # standard=1: this is a "new-style" course with an uploaded map as top level @@ -3231,7 +3656,7 @@ sub handler { my $supplementalflag=($env{'form.folderpath'}=~/^supplemental/); - if (($env{'form.folderpath'}=~/^default/) || $env{'form.folderpath'} eq "" || ($env{'form.pagepath'})) { + if (($env{'form.folderpath'}=~/^default/) || ($env{'form.folderpath'} eq "")) { $supplementalflag=0; } if ($env{'form.forcesupplement'}) { $supplementalflag=1; } @@ -3250,112 +3675,54 @@ sub handler { # Do we directly jump somewhere? - if ($env{'form.command'} eq 'direct') { - my ($mapurl,$id,$resurl); + if (($env{'form.command'} eq 'direct') || ($env{'form.command'} eq 'directnav')) { if ($env{'form.symb'} ne '') { - ($mapurl,$id,$resurl) = &Apache::lonnet::decode_symb($env{'form.symb'}); - if ($resurl=~/\.(sequence|page)$/) { - $mapurl=$resurl; - } elsif ($resurl eq 'adm/navmaps') { - $mapurl=$env{'course.'.$env{'request.course.id'}.'.url'}; - } - my $mapresobj; - my $navmap = Apache::lonnavmaps::navmap->new(); - if (ref($navmap)) { - $mapresobj = $navmap->getResourceByUrl($mapurl); - } - $mapurl=~s{^.*/([^/]+)\.(\w+)$}{$1}; - my $type=$2; - my $path; - if (ref($mapresobj)) { - my $pcslist = $mapresobj->map_hierarchy(); - if ($pcslist ne '') { - foreach my $pc (split(/,/,$pcslist)) { - next if ($pc <= 1); - my $res = $navmap->getByMapPc($pc); - if (ref($res)) { - my $thisurl = $res->src(); - $thisurl=~s{^.*/([^/]+)\.\w+$}{$1}; - my $thistitle = $res->title(); - $path .= '&'. - &Apache::lonhtmlcommon::entity_encode($thisurl).'&'. - &Apache::lonhtmlcommon::entity_encode($thistitle). - ':'.$res->randompick(). - ':'.$res->randomout(). - ':'.$res->encrypted(). - ':'.$res->randomorder(); - } - } - } - $path =~ s/^\&//; - my $maptitle = $mapresobj->title(); - if ($mapurl eq 'default') { - $maptitle = 'Main Course Documents'; - } - $path .= (($path ne '')? '&' : ''). - &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle). - ':'.$mapresobj->randompick(). - ':'.$mapresobj->randomout(). - ':'.$mapresobj->encrypted(). - ':'.$mapresobj->randomorder(); - } else { - my $maptitle = &Apache::lonnet::gettitle($mapurl); - if ($mapurl eq 'default') { - $maptitle = 'Main Course Documents'; - } - $path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle).'::::'; - } - unless ($mapurl eq 'default') { - $path = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Course Documents'). - '::::&'.$path; - } - if ($type eq 'sequence') { - $env{'form.folderpath'}=$path; - $env{'form.pagepath'}=''; - } else { - $env{'form.pagepath'}=$path; - $env{'form.folderpath'}=''; - } + $env{'form.folderpath'}= + &Apache::loncommon::symb_to_docspath($env{'form.symb'}); + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => + $env{'form.command'}.'_'.$env{'form.symb'}}); } elsif ($env{'form.supppath'} ne '') { $env{'form.folderpath'}=$env{'form.supppath'}; + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => + $env{'form.command'}.'_'.$env{'form.supppath'}}); } } elsif ($env{'form.command'} eq 'editdocs') { - $env{'form.folderpath'} = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Course Content'); - $env{'form.pagepath'}=''; + $env{'form.folderpath'} = 'default&'. + &Apache::lonhtmlcommon::entity_encode('Main Course Content'). + ':::::'; + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => $env{'form.command'}}); } elsif ($env{'form.command'} eq 'editsupp') { - $env{'form.folderpath'} = 'default&'. + $env{'form.folderpath'} = 'supplemental&'. &Apache::lonhtmlcommon::entity_encode('Supplemental Content'); - $env{'form.pagepath'}=''; + &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'}); + } elsif ($env{'form.command'} eq 'home') { + &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} => '/adm/menu'}); } + # Where do we store these for when we come back? my $stored_folderpath='docs_folderpath'; if ($supplementalflag) { $stored_folderpath='docs_sup_folderpath'; } -# No folderpath, no pagepath, and in edit mode, see if we have something stored - if ((!$env{'form.folderpath'}) && (!$env{'form.pagepath'}) && $allowed) { +# No folderpath, and in edit mode, see if we have something stored + if ((!$env{'form.folderpath'}) && $allowed) { &Apache::loncommon::restore_course_settings($stored_folderpath, {'folderpath' => 'scalar'}); + unless (&unescape($env{'form.folderpath'}) =~ m{^(default|supplemental)&}) { + undef($env{'form.folderpath'}); + } } # If we are not allowed to make changes, all we can see are supplemental docs if (!$allowed) { - $env{'form.pagepath'}=''; unless ($env{'form.folderpath'} =~ /^supplemental/) { $env{'form.folderpath'} = &supplemental_base(); } } -# If we still not have a folderpath, see if we can resurrect at pagepath - if (!$env{'form.folderpath'} && $allowed) { - &Apache::loncommon::restore_course_settings($stored_folderpath, - {'pagepath' => 'scalar'}); - } # Make the zeroth entry in supplemental docs page paths, so we can get to top level if ($env{'form.folderpath'} =~ /^supplemental_\d+/) { $env{'form.folderpath'} = &supplemental_base() @@ -3363,11 +3730,12 @@ sub handler { $env{'form.folderpath'}; } # If after all of this, we still don't have any paths, make them - unless (($env{'form.pagepath'}) || ($env{'form.folderpath'})) { + unless ($env{'form.folderpath'}) { if ($supplementalflag) { $env{'form.folderpath'}=&supplemental_base(); } else { - $env{'form.folderpath'}='default'; + $env{'form.folderpath'}='default'.&escape(&mt('Main '.$crstype.' Documents')). + ':::::'; } } @@ -3375,38 +3743,29 @@ sub handler { unless ($toolsflag) { if ($allowed) { &Apache::loncommon::store_course_settings($stored_folderpath, - {'pagepath' => 'scalar', - 'folderpath' => 'scalar'}); + {'folderpath' => 'scalar'}); } + my $folderpath; if ($env{'form.folderpath'}) { - my (@folderpath)=split('&',$env{'form.folderpath'}); - $env{'form.foldername'}=&unescape(pop(@folderpath)); - $env{'form.folder'}=pop(@folderpath); - $container='sequence'; - } - if ($env{'form.pagepath'}) { - my (@pagepath)=split('&',$env{'form.pagepath'}); - $env{'form.pagename'}=&unescape(pop(@pagepath)); - $env{'form.folder'}=pop(@pagepath); - $container='page'; - $containertag = ''. - ''; - $pathitem = - ''. - ''. - ''; + $folderpath = $env{'form.folderpath'}; + my (@folders)=split('&',$env{'form.folderpath'}); + $env{'form.foldername'}=&unescape(pop(@folders)); + if ($env{'form.foldername'} =~ /\:1$/) { + $container = 'page'; + } else { + $container = 'sequence'; + } + $env{'form.folder'}=pop(@folders); } else { - my $folderpath=$env{'form.folderpath'}; - if (!$folderpath) { - if ($env{'form.folder'} eq '' || - $env{'form.folder'} eq 'supplemental') { - $folderpath='default&'. - &escape(&mt('Main '.$crstype.' Documents')); - } + if ($env{'form.folder'} eq '' || + $env{'form.folder'} eq 'supplemental') { + $folderpath='default&'. + &escape(&mt('Main '.$crstype.' Documents')). + ':::::'; } - $containertag = ''; - $pathitem = ''; } + $containertag = ''; + $pathitem = ''; if ($r->uri=~/^\/adm\/coursedocs\/showdoc\/(.*)$/) { $showdoc='/'.$1; } @@ -3444,7 +3803,7 @@ sub handler { @tabids = ('002','ee2','ff2'); } else { @tabids = ('aa1','bb1','cc1','ff1'); - unless ($env{'form.pagepath'}) { + unless ($env{'form.folderpath'} =~ /\:1$/) { unshift(@tabids,'001'); push(@tabids,('dd1','ee1')); } @@ -3558,9 +3917,6 @@ sub handler { } elsif ((!$showdoc) && (!$uploadphase)) { # ----------------------------------------------------------------------------- my %lt=&Apache::lonlocal::texthash( - 'uplm' => 'Upload a new main '.lc($crstype).' document', - 'upls' => 'Upload a new supplemental '.lc($crstype).' document', - 'impp' => 'Import a document', 'copm' => 'All documents out of a published map into this folder', 'upfi' => 'Upload File', 'upld' => 'Import Content', @@ -3570,21 +3926,20 @@ sub handler { 'impm' => 'Import from Assembled Map', 'selm' => 'Select Map', 'load' => 'Load Map', - 'reco' => 'Recover Deleted Documents', 'newf' => 'New Folder', 'newp' => 'New Composite Page', - 'extr' => 'External Resource', 'syll' => 'Syllabus', 'navc' => 'Table of Contents', 'sipa' => 'Simple Course Page', 'sipr' => 'Simple Problem', + 'webp' => 'Blank Web Page (editable)', 'drbx' => 'Drop Box', 'scuf' => 'External Scores (handgrade, upload, clicker)', 'bull' => 'Discussion Board', 'mypi' => 'My Personal Information Page', 'grpo' => 'Group Portfolio', 'rost' => 'Course Roster', - 'abou' => 'Personal Information Page for a User', + 'abou' => 'Personal Information Page for a User', 'imsf' => 'IMS Import', 'imsl' => 'Import IMS package', 'cms' => 'Origin of IMS package', @@ -3592,9 +3947,6 @@ sub handler { 'file' => 'File', 'title' => 'Title', 'comment' => 'Comment', - 'url' => 'URL', - 'prev' => 'Preview', - 'lnk' => 'Add Link', 'parse' => 'Upload embedded images/multimedia files if HTML file', ); # ----------------------------------------------------------------------------- @@ -3619,7 +3971,7 @@ CHBO $lt{'imsf'} $help{'Importing_IMS_Course'} -
'.&mt('Resources').'$lt{'mr'}$lt{'ve'}$lt{'vu'}'.&mt('History').''.&mt('Resources').'$lt{'mr'}$lt{'ve'}$lt{'vu'}'.&mt('History').''.&Apache::lonnet::gettitle($linkurl).'
'. + '
'.&Apache::lonnet::gettitle($linkurl).'
'. ''.$linkurl.'
'.$currentversion.'
('. + '
'.$currentversion.'
('. &Apache::lonlocal::locallocaltime(&Apache::lonnet::metadata($root.'.'.$extension,'lastrevisiondate')).')
'); -# Used in course - my $usedversion=$hash{'version_'.$linkurl}; - if (($usedversion) && ($usedversion ne 'mostrecent')) { - if($usedversion != $currentversion){ + '' + ); + # Used in course + my $usedversion=$hash{'version_'.$linkurl}; + if (($usedversion) && ($usedversion ne 'mostrecent')) { + if ($usedversion != $currentversion) { $r->print(''.$usedversion.''); - }else{ + } else { $r->print($usedversion); } - } else { - $r->print($currentversion); - } - $r->print(''); -# Set version - $r->print(&Apache::loncommon::select_form($setversions{$linkurl}, - 'set_version_'.$linkurl, - {'select_form_order' => - ['',1..$currentversion,'mostrecent'], - '' => '', - 'mostrecent' => &mt('most recent'), - map {$_,$_} (1..$currentversion)})); - my $lastold=1; - for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { - my $url=$root.'.'.$prevvers.'.'.$extension; - if (&Apache::lonnet::metadata($url,'lastrevisiondate')< - $starttime) { - $lastold=$prevvers; - } - } - # - # Code to figure out how many version entries should go in - # each of the four columns - my $entries_per_col = 0; - my $num_entries = ($currentversion-$lastold); - if ($num_entries % $num_ver_col == 0) { - $entries_per_col = $num_entries/$num_ver_col; } else { - $entries_per_col = $num_entries/$num_ver_col + 1; + $r->print($currentversion); } - my $entries_count = 0; - $r->print(''); - my $cols_output = 1; - for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) { - my $url=$root.'.'.$prevvers.'.'.$extension; - $r->print(''.&mt('Version').' '.$prevvers.' ('. - &Apache::lonlocal::locallocaltime( - &Apache::lonnet::metadata($url, - 'lastrevisiondate') - ). - ')'); - if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') { - $r->print(' '.&mt('Diffs').''); - } - $r->print('
'); - if (++$entries_count % $entries_per_col == 0) { - $r->print('
'); - $cols_output++; - } - } - } - while($cols_output++ < $num_ver_col) { - $r->print(''); + $r->print(''); + # Set version + $r->print(&Apache::loncommon::select_form( + $setversions{$linkurl}, + 'set_version_'.$linkurl, + {'select_form_order' => ['',1..$currentversion,'mostrecent'], + '' => '', + 'mostrecent' => &mt('most recent'), + map {$_,$_} (1..$currentversion)})); + my $lastold=1; + for (my $prevvers=1;$prevvers<$currentversion;$prevvers++) { + my $url=$root.'.'.$prevvers.'.'.$extension; + if (&Apache::lonnet::metadata($url,'lastrevisiondate')<$starttime) { + $lastold=$prevvers; + } + } + $r->print(''); + for (my $prevvers=$lastold;$prevvers<$currentversion;$prevvers++) { + my $url=$root.'.'.$prevvers.'.'.$extension; + $r->print( + '' + .'' + .&mt('Version [_1]',$prevvers).'' + .' ('.&Apache::lonlocal::locallocaltime( + &Apache::lonnet::metadata($url,'lastrevisiondate')) + .')'); + if (&Apache::loncommon::fileembstyle($extension) eq 'ssi') { + $r->print( + ' &'). + '" target="diffs">'.&mt('Diffs').''); } - } + $r->print('
'); + } + $r->print('